给 Vue 页面加个 Markdown 编辑器:ME.js 的接入、图片粘贴与音视频
给后台加一个文章编辑框,常见的需求其实没那么复杂:能排版,能贴图,内容最好还能以 Markdown 存下来。
ME.js 做的就是这件事。它不是左边写语法、右边看预览的双栏编辑器,而是在排好版的内容上直接编辑,再把结果序列化成 Markdown。项目同时提供原生 JavaScript、Vue 3 和 React 18 三种接入文件。下面以 Vue 版为主,把接入方式和几个容易踩的点说清楚。[1][2]
先说明核对范围:本文对照了演示页和仓库提交 7f25980e99f97c746b86293f1a5bf28de159e41b,并运行了 Vue 版解析器及上传 URL 拼接的代码级测试;不是完整的浏览器兼容性测试。文中配图均为说明示意,不是产品截图。
每个文件已经包含编辑器核心,不需要先加载原生版,再叠加 Vue 或 React 适配层。项目也提供对应的演示页面,可以直接照着改。[1]
这里的“开箱即用”,指的是不用为了试一个编辑框,先准备打包器和脚手架。Vue、React 本身还是要加载。当前 Vue 文件使用全局 Vue 和字符串模板,下面也按这个方式接入,不把它写成一个尚未核实的 npm 包用法。[2]
把下面的代码保存成 HTML,通过本地静态服务打开,即可开始接入验证。示例固定了编辑器的源码版本,避免 main 分支变化后,文章里的行为跟着变。
标题放在 options.title 里。虽然演示文档里也出现了直接传 title 的写法,但当前组件声明的 props 只有 modelValue 和 options,内部导航标题读取的是 opts.title。[2]
在已有 Vue 工程中接入时,还要留意它当前是全局脚本,不是标准的单文件组件示例。不要直接把上面的代码理解成 import MeEditor from '某个包' 就能用。
图片粘贴是这个编辑器很实用的一点。当前 Vue 实现会检查剪贴板里的图片项,再根据 uploadUrl 选择处理方式:[2]
也就是说,试用时可以先不搭图床;正式用到文章后台,再把上传接口接上。
前端发送的是 POST 请求,正文为 multipart/form-data,图片字段名是 file。后端返回 JSON,其中需要有 url 字段。[2]
下面是配置形状,域名需要替换成你自己的服务,不是可以直接使用的公共接口:
建议上传地址和响应中的图片地址都使用完整的 HTTPS URL。当前实现遇到相对图片路径时,会用 new URL(uploadUrl).origin 拼接;如果 uploadUrl 也只写成 /upload,这个构造会失败,最后落到 Base64 回退。我对这段函数做了模拟响应测试,确认了这个分支。[2]
另外,文档列出了 pasteImage: 'auto' | 'base64' | 'upload',但当前 Vue 版的粘贴处理函数并没有读取这个选项,真正决定分支的是有没有 uploadUrl。因此,不能一边配置上传地址,一边指望 pasteImage: 'base64' 强制走内嵌。[1][2]
Base64 适合临时记录和小图,不适合在长文章里大量堆图。它把图片内容放进正文,保存、传输和后续编辑都要一起处理这段数据。当前状态栏又是按序列化后的 Markdown 字符串计数,一张 Base64 图片就可能让“字符数”明显上涨。[2]
如果业务要求“上传失败就不准提交”,还需要自己补失败状态和提交校验,不能把默认回退当成上传成功。
项目提供 server.py,基于 Python 标准库,可以作为本地联调的上传接收端:[1][3]
接口是 POST /upload,上传后的文件通过 /uploads/ 路径访问。[3]
这能省掉验证图片上传时临时写接口的工夫,但它不是拿来直接暴露到公网的生产图床。项目 README 也明确提醒了这一点。正式部署仍要处理鉴权、文件类型和大小校验、访问控制,以及自己的存储策略。[1]
工具栏提供音频和视频插入入口,填入资源 URL 后,编辑区插入浏览器原生的
它做的是“插入已有媒体地址”,不是内置录音、视频剪辑或转码。资源是否能播,也要看地址是否可访问、媒体编码和浏览器支持情况。
序列化时,音视频会以 HTML 标签的形式留在 Markdown 字符串里,例如:[2]
这里必须提一个当前版本的限制:能插入,不代表保存后再打开就能原样恢复。
我调用了当前 Vue 版的 MEVue.MdParser.parse(),把上面这样的音视频标签重新传进去,得到的是被转义的 HTML 文本,而不是播放器。这是解析器层面的测试结果,不是对所有浏览器播放效果的判断。[2]
来源:稀土掘金 原文