Vue3+Vite实现一个Markdown编辑器组件
作者:前端极客探险家
一、项目背景与需求分析
在现代前端开发中,Markdown 编辑器广泛应用于博客、文档、Wiki、代码注释等场景。一个优秀的 Markdown 编辑器需要具备以下功能:
- 实时预览:用户输入时,能够看到实时的渲染效果。
- 语法高亮:支持 Markdown 语法的实时高亮显示。
- 导出功能:支持将编辑的内容导出为 Markdown 或 HTML 格式,方便分享和存档。
- 自动保存:避免用户丢失未保存内容。
- 文件上传:支持上传文件(如图片),并在 Markdown 内容中嵌入显示。
本文将使用 Vue 3 构建一个简单的 Markdown 编辑器组件,并实现上述基本功能。
二、搭建基础项目
1. 初始化 Vue 3 项目
我们使用 Vite 来初始化 Vue 3 项目,并选择 TypeScript 模板:
npm create vite@latest markdown-editor --template vue-ts cd markdown-editor
2. 安装依赖
接下来,我们安装实现 Markdown 渲染和语法高亮所需要的依赖:
marked:用于将 Markdown 转换为 HTML。
highlight.js:用于提供 Markdown 语法的高亮显示。
npm install marked highlight.js
三、实现 Markdown 编辑器组件
1. 创建 Markdown 编辑器组件
在 src/components 目录下创建 MarkdownEditor.vue 文件,封装 Markdown 编辑器功能。
<template> <div class="markdown-editor"> <textarea v-model="content" class="editor-textarea" placeholder="请输入 Markdown 内容..." @input="saveToLocalStorage" ></textarea> <div class="preview"> <div v-html="renderedContent" class="preview-content"></div> </div> <div class="export-buttons"> <button @click="exportMarkdown">导出 Markdown</button> <button @click="exportHTML">导出 HTML</button> </div> <div class="file-upload"> <input type="file" @change="handleFileUpload" /> <p>上传图片并在 Markdown 中显示</p> </div> </div> </template> <script lang="ts"> import { defineComponent, ref, computed, onMounted } from 'vue'; import { marked } from 'marked'; import hljs from 'highlight.js'; export default defineComponent({ name: 'MarkdownEditor', setup() { const content = ref(''); const fileUrl = ref<string | null>(null); // 从本地存储加载内容 onMounted(() => { const savedContent = localStorage.getItem('markdown-content'); if (savedContent) { content.value = savedContent; } }); // 将 Markdown 转换为 HTML 并加上语法高亮 const renderedContent = computed(() => { marked.setOptions({ highlight: (code: string) => { return hljs.highlightAuto(code).value; }, }); return marked(content.value); }); // 保存内容到本地存储(自动保存) const saveToLocalStorage = () => { localStorage.setItem('markdown-content', content.value); }; // 导出 Markdown 内容 const exportMarkdown = () => { const blob = new Blob([content.value], { type: 'text/markdown' }); const url = URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.download = 'document.md'; link.click(); }; // 导出 HTML 内容 const exportHTML = () => { const blob = new Blob([renderedContent.value], { type: 'text/html' }); const url = URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.download = 'document.html'; link.click(); }; // 文件上传功能 const handleFileUpload = (event: Event) => { const fileInput = event.target as HTMLInputElement; const file = fileInput.files ? fileInput.files[0] : null; if (file) { const reader = new FileReader(); reader.onload = () => { const imageUrl = reader.result as string; fileUrl.value = imageUrl; // 存储图片的 URL const markdownImage = ``; // 将图片路径转化为 Markdown 格式 content.value += `\n\n${markdownImage}\n`; // 插入到 Markdown 内容中 }; reader.readAsDataURL(file); // 将图片读取为 Data URL } }; return { content, renderedContent, exportMarkdown, exportHTML, handleFileUpload, }; }, }); </script> <style scoped> .markdown-editor { display: flex; flex-direction: column; gap: 20px; padding: 20px; } .editor-textarea { width: 100%; height: 300px; padding: 10px; font-size: 16px; line-height: 1.5; border: 1px solid #ccc; border-radius: 8px; resize: none; } .preview { background-color: #f8f8f8; padding: 20px; border: 1px solid #ccc; border-radius: 8px; min-height: 300px; } .preview-content { max-width: 100%; word-wrap: break-word; } .export-buttons { display: flex; gap: 10px; } button { padding: 10px 20px; background-color: #007bff; color: white; border: none; border-radius: 8px; cursor: pointer; } button:hover { background-color: #0056b3; } .file-upload { display: flex; flex-direction: column; gap: 10px; } input[type="file"] { padding: 5px; } </style>
2. 组件说明
Markdown 渲染:通过 marked 将用户输入的 Markdown 内容转换为 HTML。
语法高亮:使用 highlight.js 对代码块进行高亮显示,增强代码阅读性。
导出功能:支持将 Markdown 或 HTML 内容导出为文件,方便用户保存或分享。
自动保存功能:使用 localStorage 自动保存 Markdown 内容,避免用户丢失未保存的输入。
文件上传支持:允许用户上传图片文件,并将图片插入到 Markdown 内容中,生成合适的 Markdown 格式。
四、优化与拓展
1. 自动保存功能
通过 localStorage 实现了自动保存功能。每次用户输入内容时,Markdown 编辑器的内容会自动存储到浏览器的本地存储中。当用户刷新页面或重新加载时,保存的内容会自动恢复。这样能有效避免用户因刷新或浏览器崩溃导致的数据丢失。
// 保存内容到本地存储(自动保存) const saveToLocalStorage = () => { localStorage.setItem('markdown-content', content.value); };
2. 文件上传功能
我们通过 HTML5 的 FileReader API 实现了文件上传支持。当用户上传图片文件时,图片会转换为 Data URL,并自动插入到 Markdown 内容中。Markdown 内容将以  格式显示上传的图片。
// 文件上传功能 const handleFileUpload = (event: Event) => { const fileInput = event.target as HTMLInputElement; const file = fileInput.files ? fileInput.files[0] : null; if (file) { const reader = new FileReader(); reader.onload = () => { const imageUrl = reader.result as string; fileUrl.value = imageUrl; // 存储图片的 URL const markdownImage = ``; // 将图片路径转化为 Markdown 格式 content.value += `\n\n${markdownImage}\n`; // 插入到 Markdown 内容中 }; reader.readAsDataURL(file); // 将图片读取为 Data URL } };
五、总结
通过 Vue 3 和 marked、highlight.js,我们实现了一个功能完善的 Markdown 编辑器组件。这个组件不仅支持实时预览,还具备了语法高亮与导出功能,极大地方便了用户的文档编辑与分享需求。同时,自动保存功能和文件上传功能进一步提升了编辑器的可用性和用户体验。
该组件可以轻松地集成到任何 Vue 3 项目中,为你的应用增添强大的编辑能力。
到此这篇关于Vue3+Vite实现一个Markdown编辑器组件的文章就介绍到这了,更多相关Vue3 Markdown编辑器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!