前言
最近一个月时间折腾了一下富文本编辑器,先后尝试了 quill、wangeditor,来记录一下我的踩坑之旅。
quill
最开始尝试了 quill,好像不支持 ts,文档也很匮乏,然后就直接放弃了,毕竟后续还要维护很长一段时间,文档不行还是很蛋疼的。
wangeditor
放弃 quill 以后,开始在 google 上搜索富文本编辑器相关的包,发现 wangeditor 的出现频率特别高。
看了一下官方文档后发现,它是基于 slate.js 二次开发的富文本编辑器,除了二次封装提供的 api 以为,你还可以直接调用 slate 提供的 api(当然,文档会比较匮乏),不过 wangeditor 二次封装的 api 已经足够开发日常使用的功能了。
开始使用
安装
yarn add @wangeditor/editor
个人建议使用原生 js 写法,这样可以在 react、vue、nuxt 等环境下渲染。
定义结构
<div id="toolbar-container"></div>
<div id="editor-container"></div>
引入 wangEditor
import '@wangeditor/editor/dist/css/style.css'
import { createEditor, createToolbar, IEditorConfig, IDomEditor } from '@wangeditor/editor'
创建编辑器
//【注意】下面使用的 typescript 语法。如用 javascript 语法,把类型去掉即可。
// 编辑器配置
const editorConfig: Partial<IEditorConfig> = {}
editorConfig.placeholder = '请输入内容'
editorConfig.onChange = (editor: IDomEditor) => {
// 当编辑器选区、内容变化时,即触发
console.log('content', editor.children)
console.log('html', editor.getHtml())
}
// 工具栏配置
const toolbarConfig: Partial<IToolbarConfig> = {}
// 创建编辑器
const editor = createEditor({
selector: '#editor-container',
config: editorConfig,
mode: 'default' // 或 'simple' 参考下文
})
// 创建工具栏
const toolbar = createToolbar({
editor,
selector: '#toolbar-container',
config: toolbarConfig,
mode: 'default' // 或 'simple' 参考下文
})
标签输入插件开发
可以基于 wangeditor 作者的插件 @metion 来进行修改。
关键代码
const { insertText, isInline, isVoid } = editor;
const newEditor = editor;
// 重写 insertText
newEditor.insertText = (t) => {
// tag 相关配置
const { showModal, hideModal } = getTagConfig(newEditor);
if (t === '#') {
setTimeout(() => {
// 展示 modal (异步,以便准确获取光标位置)
if (showModal) showModal(newEditor);
// 监听,隐藏 modal(异步,等待 modal 渲染后再监听)
setTimeout(() => {
function _hide() {
if (hideModal) hideModal(newEditor);
}
newEditor.once('fullScreen', _hide);
newEditor.once('unFullScreen', _hide);
newEditor.once('scroll', _hide);
newEditor.once('modalOrPanelShow', _hide);
newEditor.once('modalOrPanelHide', _hide);
});
});
}
// 非 '#' 则执行默认行为
insertText(t);
};