wangeditor 标签输入指南

677 阅读2分钟

前言

最近一个月时间折腾了一下富文本编辑器,先后尝试了 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);
};