WYSIWYG Editor 所见即所得编辑器 what you see is what you get
富文本编辑器技术调研
底层技术:Slate 做成一个完全插件化的编辑器框架
Gitbook和 语雀都使用了Slate作为底层编辑器
大量的二次开发,会导致研发成本大增,
富文本编辑器领域,前端开发有深坑存在,上手编辑器开发需慎重,例如
- 用户对编辑器的使用要求越来越高,比如
- 合并单元格、列表多级嵌套、协同编辑、版本对比、段落标注
- 大家都认为这是基本需求,其实这里面的技术难度是超出大家的想象
- 需要拦截阻止和代理的浏览器默认行为,保证数据的完整性和正确性
- 内容输入的多样性,比如有:打字键入、粘贴、拖拽等,每个处理起来都相当复杂
- 不确定的交互意图,比如按Delete键,不同的焦点位置有不同的情况需要考虑
主流富文本编辑器的方案
用 slate.js(但不依赖 React)为内核,升级为 L1 能力
vdom 技术(基于 snabbdom.jsopen in new window )做视图更新,model 和 view 分离,增加稳定性
富文本编辑器的技术演进
- L0 优势:技术⻔槛低,短时间内快速研发;劣势:可定制的空间⾮常有限
- L1 优势:站在浏览器肩膀上,能够满⾜ 99% 业务场景;劣势:⽆法突破浏览器本身的排版效果
- L2 优势:技术都掌控在⾃⼰⼿中,⽀持个性化排版;劣势:技术难度相当于⾃研浏览器、数据库
https://static001.geekbang.org/con/44/pdf/3673881710/file/%E5%AF%8C%E6%96%87%E6%9C%AC%E7%BC%96%E8%BE%91%E5%99%A8%E7%9A%84%E6%8A%80%E6%9C%AF%E6%BC%94%E8%BF%9B-%E7%BD%97%E9%BE%99%E6%B5%A9.pdf
富文本编辑器的技术演进 https://juejin.cn/post/7114547099739357214
富文本编辑器调研
tide JSON格式
gitee开源的编辑器
网站 https://gitee.com/oschina/tide
预览 https://oschina.gitee.io/tide
react-quill
不推荐,编辑过程卡顿明显,特别是插入图片
https://github.com/zenoamaro/react-quill 5.5k
Quill https://quilljs.com
braft-editor
https://braft.margox.cn/demos/basic
yarn add braft-editor
UI预览
全屏效果
import 'braft-editor/dist/index.css'
import React, { useState, useEffect, useRef } from 'react'
import BraftEditor from 'braft-editor'
import { debounce } from 'lodash'
type IProps = {
value?: string
}
function RichEditor({ value }: IProps, ref: React.ReactNode) {
// 设置编辑器初始内容
const innerHtml = BraftEditor.createEditorState(value)
const [state, setState] = useState(innerHtml)
useEffect(() => {
if (!value) return
const propsHtml = BraftEditor.createEditorState(value)
setState(propsHtml)
}, [value])
const onChange = debounce((editorState) => {
const htmlString = editorState.toHTML()
setState(htmlString)
}, 1000)
return <BraftEditor ref={ref} value={state} onChange={onChange} />
}
export default forwardRef(RichEditor)
父组件获取编辑器内容
import React, { useRef } from 'react';
import { RichEditor } from '@components'
function App() {
const inputRef = useRef();
function onSubmit() {
// 获取编辑器实例
const editorState = inputRef.current.getValue();
const value = editorState.toHTML();
console.log('value', value);
}
return (
<>
<RichText ref={inputRef}/>
<Button onClick={onSubmit}>提交</Button>
</>
)
}
draftjs
react 的富文本编辑器框架,不能开箱即用,但提供了很多用于开发富文本的 API。基于此,开发者能够搭建出定制化的富文本编辑器;
draftjs 有几个重要的概念:EditorState、Entity、SelectionState、CompositeDecorator
EditorState 编辑器的顶级状态对象,是一个不可变数据,表示 Draft 编辑器的整个状态,包括
- 当前文本内容状态(ContentState)
- 当前选择状态(SelectionState)
- 内容的装饰器(Decorator)
- 撤销/重做
- 堆栈对内容所做的最新类型的更改(EditorChangeType)
draftjs缺点
显示表格结构时,编辑器将会变慢,代码也会变得复杂
simditor
https://simditor.tower.im/
图片上传方式,可以定义尺寸,具体配置还需自己去写
pell
最小最简单的 web 富文本编辑器
https://github.com/jaredreich/pell
react 案例 https://github.com/jaredreich/pell/blob/master/examples/react.md
纯 es6,无依赖
Tiptap Vue
专为 vue.js 打造
Github https://github.com/ueberdosis/tiptap
网站 https://tiptap.dev
Tiptap 最大的特点是预置的渲染,没有任何 CSS,用户可以更全面地控制段落标记和样式
- 支持获取 HTML 字符串,开发者可以将数据储存为原始 HTML 字符串
- 支持获取 JSON 文档的 -serializable 格式
- 文档的可编辑性基于 contentEditable 属性