软件论道一:能力与复杂度
1114
2022-05-30
DevUI 是一款面向企业中后台产品的开源前端解决方案,它倡导沉浸、灵活、至简的设计价值观,提倡设计者为真实的需求服务,为多数人的设计,拒绝哗众取宠、取悦眼球的设计。如果你正在开发 ToB 的工具类产品,DevUI 将是一个很不错的选择!
引言
富文本编辑器大概是最复杂、使用场景却极广的组件了。
可以说富文本编辑器让Web数据录入充满了无限的想象空间,如果只有文本框、下拉框这些纯文本的数据录入组件,那么Web的数据录入能力将极大地受限。我们将无法在网页上插入图片、视频这些富文本内容,更无法插入自定义的内容。
富文本编辑器让Web内容编辑变得更轻松、更高效,我们几乎可以在富文本编辑器中插入任何你想插入的内容,图片、视频、超链接、公式、代码块,都不在话下,甚至还可以插入表格、PPT、思维导图,甚至3D模型这种超复杂的自定义内容。
富文本编辑器的场景在Web上也是随处可见,写文章、写评论、意见反馈、录需求单,都需要使用到富文本。
本文结合DevUI团队在富文本组件中的实践,从使用场景、技术选型,再到对Quill的扩展,以及Quill的基本原理,跟大家分享Quill富文本编辑器的那些事儿。
本文主要由以下部分组成:
富文本编辑器的使用场景
技术选型
我们为什么选择Quill
如何扩展Quill
Quill基本原理
以下内容来自Kagol在华为 HWEB 大前端技术分享会上的演讲。
富文本编辑器的使用场景
博客文章
Wiki词条
工作项描述
测试用例步骤
反馈意见
评论
…
技术选型
我们的需求:
开源协议友好
Angular框架或框架无关
灵活可扩展
支持插入/编辑表格和图片
插件丰富,生态好
选型分析
首先排除官方不维护的UEditor
然后排除React框架专属的Draft.js和Slate
接着排除开源协议不友好的CKEditor
由于我们的业务场景丰富,需要富文本插入/编辑表格的功能,所以还需要排除不支持表格的Trix,弱支持表格的Etherpad和Prosemirror,以及表格功能收费的TinyMCE
最后只剩下Quill和wangEditor两款编辑器可选,wangEditor的扩展性和生态不如Quill,所以最终选择Quill作为富文本组件的基座
为什么选择Quill?
BSD协议,商业友好
文档详细,上手快
API驱动,扩展性好
插件丰富,生态好
文档详细
Document:https://quilljs.com/
介绍Quill的API:
介绍如何扩展Quill:
上手快
安装Quill:npm i quill
引入样式:@import 'quill/dist/quill.snow.css';
引入Quill:import Quill from 'quill';
初始化Quill:new Quill('#editor', { theme: 'snow' });
效果图:
API驱动,扩展性好
插件丰富,生态好
扩展Quill
插入标签
比如我想在编辑器里插入标签
上传附件
比如我想在编辑器里插入附件
插入表情
比如我想在编辑器中插入表情
类似语雀的评论:https://www.yuque.com/yuque/blog/sguhed
个性分割线
比如我想插入B站这种个性化的分割线
超链接卡片
比如我想插入知乎这样的超链接卡片
如何插入表情?
我们从如何插入表情入手,一起看看怎么在Quill中插入自定义的内容。
要在Quill中插入表情,只需要以下四步:
第一步:自定义工具栏按钮
第二步:自定义Blot内容EmojiBlot
第三步:在Quill注册EmojiBlot
第四步:调用Quill的API插入表情
第一步:自定义工具栏按钮
const quill = new Quill('#editor', { theme: 'snow', modules: { // 配置工具栏模块 toolbar: { container: [ …, [ 'emoji' ] ], // 增加一个按钮 handlers: { // 添加按钮的处理逻辑 emoji() { console.log('插入表情'); } } }, } });
给工具栏按钮增加图标
// 扩展Quill内置的icons配置 const icons = Quill.import('ui/icons'); icons.emoji = ‘’; // 图标的svg可以从iconfont网站复制
效果如下:
工具栏上已经多了一个表情的按钮,并且能够响应鼠标点击事件,下一步就是要
编写插入表情的具体逻辑,这涉及到Quill的自定义内容相关的知识。
第二步:自定义Blot内容EmojiBlot
Quill中的Blot就是一个普通的ES6 Class,由于表情和图片的差别就在于:
Quill内置的图片格式不支持自定义宽高,而我们要插入的表情是需要特定的宽高的。
因此我们可以基于Quill内置的image格式来扩展。
emoji.ts
import Quill from 'quill'; const ImageBlot = Quill.import('formats/image'); // 扩展Quill内置的image格式 class EmojiBlot extends ImageBlot { static blotName = 'emoji'; // 定义自定义Blot的名字(必须全局唯一) static tagName = 'img'; // 自定义内容的标签名 // 创建自定义内容的DOM节点 static create(value): any { const node = super.create(value); node.setAttribute('src', ImageBlot.sanitize(value.url)); if (value.width !== undefined) { node.setAttribute('width', value.width); } if (value.height !== undefined) { node.setAttribute('height', value.height); } return node; } // 返回options数据 static value(node): any { return { url: node.getAttribute('src'), width: node.getAttribute('width'), height: node.getAttribute('height') }; } } export default EmojiBlot;
第三步:在Quill注册EmojiBlot
有了EmojiBlot,要将其插入Quill编辑器中,还需要将这个ES6类注册到Quill中。
import EmojiBlot from './formats/emoji'; Quill.register('formats/emoji', EmojiBlot);
第四步:调用Quill的API插入表情
EmojiBlot注册到Quill中之后,Quill就能认识它了,也就可以调用Quill的API将其插入到编辑器中。
emoji(): void { console.log(‘插入表情'); // 获取当前光标位置 const index = this.quill.getSelection().index; // 在当前光标处插入emoji(blotName) this.quill.insertEmbed(index, 'emoji', { url: 'assets/emoji/good.png', width: '64px', }); },
效果图
Demo源码
源码链接:https://gitee.com/kagol/quill-demo
也欢迎关注我们DevUI组件库的官网,了解更多有趣又实用的开源组件!
DevUI官网:https://devui.design
Quill基本原理
最后讲一讲Quill的基本原理。
基本原理
使用Delta数据模型描述富文本内容及其变化,以保证行为的可预测
通过Parchment对DOM进行抽象,以保证平台一致性
通过Mutation Observe监听DOM节点的变化,将DOM的更改同步到Delta数据模型中
Quill如何表达编辑器内容?
Delta数据模型
通过Delta数据模型来描述富文本内容及其变化
Delta 是JSON的一个子集,只包含一个 ops 属性,它的值是一个对象数组,每个数组项代表对编辑器的一个操作(以编辑器初始状态为空为基准)。
{ "ops": [ { "insert": "Hello " }, { "insert": "World", "attributes": { "bold": true } }, { "insert": "\n" } ] }
修改编辑器内容
比如我们把加粗的"World"改成红色的文字"World",这个动作用 Delta 描述如下:
{ "ops": [ { "retain": 6 }, { "retain": 5, "attributes": { "color": "#ff0000" } } ] }
意思是:保留编辑器最前面的6个字符,即保留"Hello “不动,保留之后的5个字符"World”,并将这些字符设置为字体颜色为"#ff0000"。
删除编辑器内容
如果要删除"World"呢?
{ "ops": [ { "retain": 6 }, { "delete": 5 } ] }
即:保留前面6个字符(’Hello ’),删除之后的5个字符(’World’)
Quill如何渲染内容?
渲染富文本内容的基本原理:
遍历Delta数组,将其中描述的内容一个一个应用(插入/格式化/删除)到编辑器中。
详情可参考DevUI专栏文章:
《Quill的内容渲染机制》
Quill如何扩展编辑器的能力?
扩展Quill的方式:
通过自定义Blot格式来扩展编辑器的内容
通过自定义模块来扩展编辑器的功能
详情可参考DevUI专栏文章:
《现代富文本编辑器Quill的模块化机制》
THANK YOU!
web前端
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。