Quill富文本編輯器的實踐 - DevUI

      網友投稿 1237 2025-04-01

      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' });

      效果圖:

      Quill富文本編輯器的實踐 - DevUI

      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小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:ASM磁盤操作命令
      下一篇:新建電子表格(新建電子表格打不開是什么原因)
      相關文章
      久久亚洲精品中文字幕三区| 亚洲色自偷自拍另类小说| 久久精品夜色国产亚洲av| 最新亚洲成av人免费看| 亚洲性在线看高清h片| 亚洲精品456播放| 亚洲国产精品人人做人人爽| 亚洲av麻豆aⅴ无码电影| 国产精品无码亚洲一区二区三区| 亚洲色大情网站www| 亚洲色大成WWW亚洲女子| 亚洲AV无码成人网站在线观看| 久久亚洲中文无码咪咪爱| 久久精品国产亚洲av瑜伽| 日韩色视频一区二区三区亚洲| 亚洲av无码成人影院一区| 国产成人亚洲精品91专区高清| 亚洲成年看片在线观看| 亚洲人成国产精品无码| 国产精品亚洲产品一区二区三区 | 亚洲精品成人网久久久久久| 亚洲一区二区三区无码影院| 久久久久亚洲爆乳少妇无| 亚洲精品tv久久久久久久久| 亚洲爆乳无码专区| 97久久精品亚洲中文字幕无码 | 亚洲人成色77777在线观看大| 亚洲欧洲自拍拍偷精品 美利坚 | 亚洲国产最大av| 亚洲精品国产首次亮相| 夜色阁亚洲一区二区三区| 亚洲一区二区三区在线视频| 国产亚洲综合色就色| 亚洲视频2020| 亚洲伊人久久精品| 亚洲真人无码永久在线观看| 久久水蜜桃亚洲AV无码精品| 亚洲精品视频在线看| 国产亚洲一区二区三区在线| 亚洲美免无码中文字幕在线| 亚洲91精品麻豆国产系列在线|