easyhr-wangeditor-plugin-magic
v0.1.0-alpha.1
Published
wangEditor magic plugin
Readme
wangEditor magic 插件
介绍
wangEditor magic 插件(变量库),在编辑器中输入 # 会唤起选择弹框,选中后插入 magic 节点,如 #张三#。

安装
yarn add @kxb/wangeditor-plugin-magic使用
注册到编辑器
import { IDomEditor, Boot, IEditorConfig } from '@wangeditor/editor'
import magicModule, { MagicElement } from '@kxb/wangeditor-plugin-magic'
// 注册。要在创建编辑器之前注册,且只能注册一次,不可重复注册。
Boot.registerModule(magicModule)
// 显示弹框
function showModal(editor: IDomEditor) {
// 获取光标位置,定位 modal
const domSelection = document.getSelection()
const domRange = domSelection?.getRangeAt(0)
if (domRange == null) return
const selectionRect = domRange.getBoundingClientRect()
// 获取编辑区域 DOM 节点的位置,以辅助定位
const containerRect = editor.getEditableContainer().getBoundingClientRect()
// 显示 modal 弹框,并定位
// PS:modal 需要自定义,如 <div> 或 Vue React 组件
// 当触发某事件(如点击一个选项)时,插入 magic 节点
function insertMagic() {
const magicNode: MagicElement = {
type: 'magic', // 必须是 'magic'
value: '张三', // 文本
info: { x: 1, y: 2 }, // 其他信息,自定义
children: [{ text: '' }], // 必须有一个空 text 作为 children
}
editor.restoreSelection() // 恢复选区
editor.deleteBackward('character') // 删除 '#'
editor.insertNode(magicNode) // 插入 magic 节点
editor.move(1) // 移动光标
}
}
// 隐藏弹框
function hideModal(editor: IDomEditor) {
// 隐藏 modal
}
// 编辑器配置
const editorConfig: Partial<IEditorConfig> = {
EXTEND_CONF: {
magicConfig: {
showModal, // 必须
hideModal, // 必须
},
},
// 其他...
}
// 创建编辑器和工具栏,会用到 editorConfig 。具体查看 wangEditor 文档工具栏菜单
插件注册了一个 key 为 magic 的工具栏菜单(标题为「变量库」),点击后同样会调用 showModal。
createToolbar({
editor,
selector: '#toolbar-container',
config: {
toolbarKeys: ['magic'],
},
})显示 HTML
magic 节点返回的 HTML 格式如下,其中 data-info 的值需要 decodeURIComponent 解析。
<span data-w-e-type="magic" data-w-e-is-void data-w-e-is-inline data-value="张三" data-info="%7B%22x%22%3A10%7D"> #张三# </span>进阶:动态数据源与 Ant Design Vue Select 集成
插件对下拉的 UI 与数据源不做任何假设——它只通过 EXTEND_CONF.magicConfig.showModal / hideModal 两个回调把控制权交给宿主,宿主可自由决定用什么组件库渲染、数据从哪里来。这与 wangEditor 官方 mention 插件(@wangeditor/plugin-mention)的契约完全一致。
example/目录下的下拉只是「最小可运行演示」:列表数据写死在 HTML 里、纯手写 DOM 渲染,不代表插件的使用方式。
数据源应由宿主提供
- 插件不感知数据源。按业务单元(如模板 ID、页面 code)异步加载、缓存、远程搜索,均由宿主实现。
- 选中后写入 magic 节点的
info字段承载业务数据(如{ id, code })。注意info会被JSON.stringify写入 HTML 的data-info,必须是 JSON 可序列化的普通对象。
可用 ant-design-vue 4.x 的 Select 替换手写下拉
关键 API::open(受控展开)、getPopupContainer / dropdownStyle(定位)、show-search + @search(远程搜索)、:loading / not-found-content(加载与空态)、@select(取回完整业务对象)。键盘 ↑↓ / Enter / Esc 由组件原生支持。
两个必须守住的时序:
showModal中先取光标getBoundingClientRect(),再让 Select 抢焦点,顺序反了定位会错。- 选中时先
editor.restoreSelection(),再deleteBackward('character')删掉触发用的#,最后insertNode+move(1)。
注意:从工具栏「变量库」按钮打开下拉时并没有插入
#,此时不应执行deleteBackward,否则会误删光标前的一个真实字符。
以上均为宿主侧集成方案,插件层(src/)无需改动。详细设计与完整参考代码(数据源抽象、Vue 3 + ant-design-vue 4 组件、桥接层)见 DESIGN-datasource-antd-select.md。
本地开发
yarn dev启动本地服务(端口 3000),使用example目录yarn test单元测试,使用test目录yarn build构建代码,使用src目录
发布
yarn build
yarn publish --registry http://192.168.40.243:8888/repository/npm-hosted/