背景
项目需要,需要使用可实现自定义的富文本编辑器。所以就找了市面上的一些富文本编辑器进行对比选型。由于我们采用的是react实现的前端开发,本次需要对于富文本编辑器需要有个较为深度的自定义。所以,我对市面上常用的几款富文本编辑器做了一个选型对比表格。
框架
|
功能
|
实操
|
|||||
基础文本编辑
|
表格操作
|
表格语义化
|
上手难度
|
风险项
|
优势
|
是否付费
|
|
Draft.js
|
支持
|
支持
|
支持,自定义组件【契合度高】
|
中度
|
1、操作栏需要自己绘制,适配,基础功能非开箱即用
2、不支持osx按键绑定
3、UI绘制、适配可能比较耗时
4、不兼容html互转
5、复杂结构【table】编辑器会卡顿
|
1、facebook自研,支持react,组件化较高
2、插件支持
3、数据视图分离
|
否
|
Slate.js
|
支持
|
支持
|
支持
|
中度
|
1、对外复制粘贴功能不完善
2、slate-react实现基于hook,依赖hook
|
1、核心包与页面渲染包分离,支持前端框架的自定义
2、插件支持
3、支持react
|
否
|
Quill.js
|
支持
|
支持,需要三方插件
|
不支持
|
一般
|
1、富文本复制存在丢失问题
2、功能定制较为有限
3、不支持插件
|
1、有预设样式
|
|
TinyMCE
|
支持
|
支持
|
支持
|
中度
|
1、不支持react组件化,需要兼容实现,与vue更友好
2、2020年开始基于slate进行富文本的开发
3、高级功能需要收费,其中包括表格
|
1、比较成熟
2、预设样式较为美观
3、插件支持
|
有免费版和商用版
|
KendoReact
|
支持
|
支持
|
支持
|
/
|
需要付费,首次使用可以申请一个免费期限
|
1、高性能
2、高度可定制
3、插件支持
4、react支持
|
是
|
综合各方面元素,最终决定了选择slatejs作为富文本开发框架来帮助实现功能。
使用
既然选定了slatejs来作为富文本编辑器。slatejs怎么怎么优美,又是怎么怎么强大,咱先暂时抛开,看看如何去使用才是王道。
安装
常规第一步,不论啥框架,先把依赖安装了再说
$ npm i slate slate-react --save-dev // 或者 $ yarn add slate slate-react -D
基于react去应用了,react和react-dom安装就不说了,忘记装的,自己装下。
使用
这里,我就不分步骤一个个放代码了,给个终结的,再简单介绍几句就完事了。你好我好大家都好。
import React, { useState, useCallback } from 'react' import { createEditor, Editor, Transforms } from 'slate'; import { Slate, Editable, withReact } from 'slate-react'; const initialValue = [ // 设置操作栏初始配置 { type: 'paragraph', children: [{ text: 'A line of text in a paragraph.' }], }, ] const CodeElement = (props) => { // 自定义格式化代码组件 return ( <pre {...props.attributes}> <code>{props.children}</code> </pre>); }; const DefaultElement = (props) => { return <p {...props.attributes}>{props.children}</p>; }; const SlateEditor: React.FC = (props) => { const editor = useMemo(() => withReact(createEditor()), []); const renderElement useCallback((props) => { switch (props.element.type) { case 'code': return <CodeElement {...props} />; default: return <DefaultElement {...props} />; } }, []); return ( <Slate editor={editor} value={initialValue}> <Editable onKeyDown={(event) => { if (event.key === '`' && event.ctrlKey) { event.preventDefault(); Transforms.setNodes( editor, { type: 'code' }, { match: (n) => Editor.isBlock(editor, n) }, ); } } } /> </Slate> ); };
如上通过Slate 配置 onKeyDown来创建富文本的句柄监听按键实践,通过Tranforms添加自定义组件CodeElement。