markdown-编辑器技术实现

技术选型

  • 项目脚手架vuecli 3.0(后续会单独整理补充下项目脚手架系列)
  • vue全家桶(vue、vuex和vue-router和等)
  • markdown-it和相关插件
  • npm发包相关

模块拆解和设计思路

文档输入区域

文档输入区域是一个随内容增多自动升高的容器,实现该效果有还多种方法,我采用texarea和pre组合实现。pre visibility hidden, texarea overflow hidden,它们两个共同重叠,实现撑开父容器。
根据输入内容的类别,抽象输入工具库。基本输入和特殊输入分别处理。

文档渲染区域

通过markdown-it渲染引擎的render实现输入内容的实时渲染,同时支持特殊内容的处理,如通过事件代理实现图片点击预览,放大缩小等功能。

数据同步

由于markdown渲染几乎是实时的,因此我们通过vuex来实现输入区和渲染区处理的是同一内容。

快捷输入

该功能分为两部分,第一:通过抽象好的输入工具库实现顶部快捷键点击输入,第二:键盘快捷键封装,结合输入板工具库实现快捷键插入内容。

markdown-it和插件部分

markdown-it解析引擎包含以下几部分:

  • 构造函数 const md = new MarkdownIt(config)
  • 引入第三方插件plugin import plugin from ‘xxx’
  • 自定义插件扩展
  • 挂载插件 md.use(plugin)
  • markdown语法渲染 md.render(str)
    其中插件的引入设计需要考虑支持用户自定义配置插件引入或者挂载,甚至支持动态按需引入插件。

npm包设计

markdown编辑器作为一个独立的模块,它需要独立发npm包来方便的支撑其它项目。同时该独立的模块本身也有实际使用的demo展示。因此,基于vue的模块使用规范,我们使用install 和 全局 components注册的方式来导出npm module。

1
2
3
4
5
6
7
8
9
10
11
12
13
import editor from './views/editor'
import markdownIt from './utils/md'
import markdownBody from './store/modules/markdownBody'
const pmdEditor = {
markdownIt: markdownIt,
editor: editor,
install: function (Vue, options = {}) {
Vue.component('pmd', editor)
options.store && options.store.registerModule('markdownBody', markdownBody)
}
}

export default pmdEditor

源码

欢迎fork star

本文结束感谢您的阅读