官网:www.wangeditor.com/v5/ 【V5 已经停止新增功能,仅可继续使用】 底层基于 Slate,分为 编辑器实例 + 工具栏实例 两个独立对象
一、快速接入(原生JS)
1. 安装
npm install @wangeditor/editor --save
2. 最简Demo
<div id="toolbar-container"></div>
<div id="editor-container"></div>
<script type="module">
import '@wangeditor/editor/dist/css/style.css'
import { createEditor, createToolbar } from '@wangeditor/editor'
const editor = createEditor({
selector: '#editor-container',
html: '<p>初始内容</p>',
config: {
placeholder: '请输入内容...',
onChange(editor) {
console.log('html:', editor.getHtml())
console.log('json:', editor.children)
}
}
})
const toolbar = createToolbar({
editor,
selector: '#toolbar-container',
config: {
// 工具栏菜单配置
}
})
</script>
二、editor 配置(createEditor 的 config)
editorConfig = {
placeholder: '请输入',
readOnly: false, // 只读
autoFocus: true, // 自动聚焦
maxLength: null, // 最大字符数
// 生命周期
onCreated(editor) {}, // 创建完成
onChange(editor) {}, // 内容/选区变化
onDestroyed(editor) {}, // 销毁
onBlur(editor) {},
onFocus(editor) {},
// 粘贴
pasteFilterStyle: true, // 过滤粘贴样式
pasteIgnoreImg: false, // 忽略粘贴图片
// 图片上传
MENU_CONF: {
uploadImage: {
server: '/api/upload',
fieldName: 'file',
maxFileSize: 2 * 1024 * 1024,
allowedFileTypes: ['image/*'],
// 自定义上传
customUpload(file, insertFn) {
// 上传成功后 insertFn(url, alt, href)
}
},
// 视频上传 uploadVideo 同理
},
// 自定义菜单、hoverbar、弹窗
hoverbarKeys: {},
EXTEND_CONF: {}
}
三、toolbar 工具栏配置
toolbarConfig = {
toolbarKeys: [
// 全部菜单 key
'bold', 'underline', 'italic', 'strikeThrough',
'color', 'bgColor', 'fontSize', 'fontFamily',
'headerSelect', 'blockquote', 'codeBlock',
'link', 'insertImage', 'insertVideo', 'insertTable',
'divider', 'undo', 'redo', 'fullScreen', 'code',
],
excludeKeys: [], // 排除不需要的菜单
modalAppendToBody: true, // 弹窗挂载body
}
菜单key清单
文本样式:bold、italic、underline、strikeThrough、color、bgColor、fontSize、fontFamily
块级:headerSelect、header1、header2、blockquote、codeBlock、divider
插入:link、insertImage、insertVideo、insertTable
列表:bulletedList、numberedList
对齐:justifyLeft、justifyCenter、justifyRight、justifyJustify
其他:undo、redo、fullScreen、print、code
四、editor 实例 API(核心)
// -------- 内容读写 --------
editor.getHtml() // 获取HTML字符串(存数据库用)
editor.getHtml({ format: true })
editor.getJson() // 获取JSON结构(等价editor.children)
editor.getText() // 获取纯文本
editor.setHtml('<p>xxx</p>') // 设置HTML
editor.setContent([...json]) // 设置JSON内容
// -------- 选区 & 光标 --------
editor.focus() // 聚焦;focus(true) 光标跳到末尾
editor.blur()
editor.isFocused() // true/false
editor.getSelection() // 获取选区
editor.restoreSelection()
editor.saveSelection()
// -------- 插入内容 --------
editor.insertText('文字')
editor.insertHtml('<p>xxx</p>')
editor.insertNode({ type: 'paragraph', children: [{text: 'xxx'}] })
// -------- 禁用/只读 --------
editor.enable()
editor.disable()
editor.isDisabled()
// -------- 全屏 --------
editor.isFullScreen
editor.toggleFullScreen()
// -------- 销毁 --------
editor.destroy()
// -------- 上传进度 --------
editor.showProgressBar(0~100)
editor.hideProgressBar()
// -------- 滚动 --------
editor.scrollToElem(elemId)
⚠️
updateView()内部API,不建议频繁调用
五、内容节点结构(JSON)
wangEditor 是 slate 节点树,不要自己随便拼HTML,优先用 editor.getHtml() 保存:
[
{
type: 'paragraph',
children: [
{ text: '普通文字', bold: true, color: '#f00' }
]
}
]
常用 type:paragraph、header1/header2...、blockquote、codeBlock、table、image、video、link
六、图片/视频上传(高频)
MENU_CONF: {
uploadImage: {
server: '/api/upload',
// 后端返回格式必须:{ "errno":0, "data": { "url": "xxx" } }
// 自定义上传(axios/fetch)
customUpload: async (file, insertFn) => {
const fd = new FormData()
fd.append('file', file)
const res = await fetch('/api/upload', {method:'POST', body:fd})
const json = await res.json()
insertFn(json.url, '图片alt', json.url)
}
}
}
七、Vue3 / React 官方组件
Vue3
<template>
<div style="border:1px solid #ccc">
<Toolbar :editor="editorRef" />
<Editor v-model="valueHtml" :defaultConfig="editorConfig" @onCreated="handleCreated"/>
</div>
</template>
<script setup>
import { ref, shallowRef } from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import '@wangeditor/editor/dist/css/style.css'
const editorRef = shallowRef()
const valueHtml = ref('<p>hello</p>')
const editorConfig = { placeholder: '请输入' }
const handleCreated = (editor) => { editorRef.value = editor }
</script>
Vue3 编辑器实例必须用
shallowRef
八、常见坑 & 注意事项
- HTML 兼容性限制:只能识别
editor.getHtml()输出的HTML,不支持任意外部HTML(比如<span style="font-weight:bold">识别不了,只认<strong>) - 不要直接操作内部DOM,全部走 editor API
- 表单提交:存
getHtml(),不要存 JSON;JSON适合实时协作、二次编辑 - 销毁:弹窗/路由离开时一定要
editor.destroy(),否则内存泄漏 - 粘贴Word:默认会过滤大量样式,如需保留样式要调整
pasteFilterStyle
九、常用自定义扩展
- 自定义按钮/菜单:
registerMenu - 自定义元素(公式、附件、代码块增强):
registerElement - 自定义渲染、自定义hover悬浮菜单