1. 为什么你需要一个自己的Markdown编辑器?
如果你经常写技术博客、项目文档,或者需要整理大量笔记,Markdown 绝对是你离不开的工具。它简洁、高效,能让你专注于内容本身,而不是排版。但市面上的在线编辑器,要么功能臃肿,要么样式固定,要么就是网络一断就抓瞎。
我经历过好几次,在某个在线编辑器里写了大半天,结果浏览器崩溃,内容全丢,那种感觉真是欲哭无泪。所以,自己动手搭建一个本地优先、功能定制、性能流畅的 Markdown 编辑器,就成了一个非常实际的需求。
用 Vue 3 来做这件事,简直再合适不过了。Vue 3 的组合式 API 让逻辑组织变得无比清晰,响应式系统又极其高效。再配上 Vite 这个“闪电侠”级别的构建工具,开发体验爽到飞起,热更新几乎无感。最后,用 Highlight.js 给代码块穿上漂亮的“外衣”,一个既实用又好看的编辑器就初具雏形了。
这个教程,我会带你从零开始,一步步搭建一个功能完整的编辑器。我们不止要实现基础的实时预览和语法高亮,还会加入自动保存、文件导出、图片上传这些提升幸福感的功能。更重要的是,我会分享我在实际开发中踩过的坑和优化技巧,让你少走弯路。无论你是 Vue 新手想找个实战项目练手,还是有一定经验想深入了解现代前端工具链,这篇文章都能给你带来实实在在的收获。
2. 快速搭建开发环境:Vite + Vue 3
万事开头难?不,用现在的工具链,开头可以非常简单。我们选择 Vite 来初始化项目,它比传统的 Webpack 快太多了,尤其是在启动和热更新的时候,那种秒开的体验,用过就回不去了。
2.1 一步创建项目骨架
打开你的终端,执行下面这条命令。这里我们直接使用 TypeScript 模板,TypeScript 能提供更好的类型提示和代码可维护性,对于稍复杂的项目来说,绝对是值得的投资。
npm create vite@latest markdown-editor -- --template vue-ts
cd markdown-editor
命令执行完后,一个基础的 Vue 3 + TypeScript 项目结构就生成了。接下来,我们安装核心的功能依赖。
2.2 安装核心功能库
我们需要两个核心库:marked 负责把 Markdown 语法转换成 HTML,highlight.js 负责给转换后的代码块进行语法高亮。
npm install marked highlight.js
这里有个小细节,我建议你也把 @types/marked 和 @types/highlight.js 装上,这样在 TypeScript 项目里能获得完美的类型提示。
npm install -D @types/marked @types/highlight.js
安装完成后,先别急着写代码。我们可以先跑起来看看初始项目的样子,执行 npm run dev,浏览器打开 http://localhost:5173,看到 Vue 的欢迎页面,说明环境一切正常。
3. 构建编辑器核心:组件设计与响应式联动
基础架子搭好了,现在我们来打造最核心的部分——编辑器组件。我会把组件拆解成几个部分来讲,确保你能理解每一行代码的作用。
3.1 组件结构:双栏布局的经典设计
我们先在 src/components 目录下创建一个 MarkdownEditor.vue 文件。经典的 Markdown 编辑器布局通常是左右分栏:左边是纯文本编辑区,右边是实时渲染的预览区。下面我们用 Vue 3 的 <script setup> 语法来写,这是目前最推荐的方式,代码更简洁。
<template>
<div class="markdown-editor">
<!-- 编辑区 -->
<textarea
v-model="markdownText"
class="editor-area"
placeholder="开始书写你的 Markdown..."
@input="handleInput"
></textarea>
<!-- 预览区 -->
<div class="preview-area">
<div
class="preview-content markdown-body"
v-html="renderedHtml"
></div>
</div>
</div>
</template>
模板部分很直观:一个 textarea 绑定到我们的响应式数据 markdownText,一个 div 用来展示渲染后的 HTML。注意,我们给预览区的容器加了一个 markdown-body 的类,这是为后续引入 GitHub 风格的 CSS 做准备。
3.2 响应式逻辑:让数据流动起来
接下来是 <script setup> 部分,这里是整个组件的“大脑”。我们首先导入必要的库

478

被折叠的 条评论
为什么被折叠?



