日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

Quill富文本编辑器的实践

發(fā)布時(shí)間:2023/12/29 综合教程 33 生活家
生活随笔 收集整理的這篇文章主要介紹了 Quill富文本编辑器的实践 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

DevUI 是一款面向企業(yè)中后臺產(chǎn)品的開源前端解決方案,它倡導(dǎo)沉浸靈活至簡的設(shè)計(jì)價(jià)值觀,提倡設(shè)計(jì)者為真實(shí)的需求服務(wù),為多數(shù)人的設(shè)計(jì),拒絕嘩眾取寵、取悅眼球的設(shè)計(jì)。如果你正在開發(fā) ToB工具類產(chǎn)品,DevUI 將是一個很不錯的選擇!

引言

富文本編輯器大概是最復(fù)雜、使用場景卻極廣的組件了。

可以說富文本編輯器讓W(xué)eb數(shù)據(jù)錄入充滿了無限的想象空間,如果只有文本框、下拉框這些純文本的數(shù)據(jù)錄入組件,那么Web的數(shù)據(jù)錄入能力將極大地受限。我們將無法在網(wǎng)頁上插入圖片、視頻這些富文本內(nèi)容,更無法插入自定義的內(nèi)容。

富文本編輯器讓W(xué)eb內(nèi)容編輯變得更輕松、更高效,我們幾乎可以在富文本編輯器中插入任何你想插入的內(nèi)容,圖片、視頻、超鏈接、公式、代碼塊,都不在話下,甚至還可以插入表格、PPT、思維導(dǎo)圖,甚至3D模型這種超復(fù)雜的自定義內(nèi)容。

富文本編輯器的場景在Web上也是隨處可見,寫文章、寫評論、意見反饋、錄需求單,都需要使用到富文本。

本文結(jié)合DevUI團(tuán)隊(duì)在富文本組件中的實(shí)踐,從使用場景、技術(shù)選型,再到對Quill的擴(kuò)展,以及Quill的基本原理,跟大家分享Quill富文本編輯器的那些事兒。

本文主要由以下部分組成:

富文本編輯器的使用場景
技術(shù)選型
我們?yōu)槭裁催x擇Quill
如何擴(kuò)展Quill
Quill基本原理

以下內(nèi)容來自Kagol華為 HWEB 大前端技術(shù)分享會上的演講。

富文本編輯器的使用場景

博客文章
Wiki詞條
工作項(xiàng)描述
測試用例步驟
反饋意見
評論

技術(shù)選型

我們的需求:

開源協(xié)議友好
Angular框架或框架無關(guān)
靈活可擴(kuò)展
支持插入/編輯表格和圖片
插件豐富,生態(tài)好

選型分析

首先排除官方不維護(hù)的UEditor
然后排除React框架專屬的Draft.jsSlate
接著排除開源協(xié)議不友好的CKEditor
由于我們的業(yè)務(wù)場景豐富,需要富文本插入/編輯表格的功能,所以還需要排除不支持表格的Trix,弱支持表格的EtherpadProsemirror,以及表格功能收費(fèi)的TinyMCE
最后只剩下QuillwangEditor兩款編輯器可選,wangEditor的擴(kuò)展性和生態(tài)不如Quill,所以最終選擇Quill作為富文本組件的基座

為什么選擇Quill?

BSD協(xié)議,商業(yè)友好
文檔詳細(xì),上手快
API驅(qū)動,擴(kuò)展性好
插件豐富,生態(tài)好

文檔詳細(xì)

Document:https://quilljs.com/

介紹Quill的API:

介紹如何擴(kuò)展Quill:

上手快

安裝Quill:npm i quill
引入樣式:@import 'quill/dist/quill.snow.css';
引入Quill:import Quill from 'quill';
初始化Quill:new Quill('#editor', { theme: 'snow' });

效果圖:

API驅(qū)動,擴(kuò)展性好

插件豐富,生態(tài)好

擴(kuò)展Quill

插入標(biāo)簽

比如我想在編輯器里插入標(biāo)簽

上傳附件

比如我想在編輯器里插入附件

插入表情

比如我想在編輯器中插入表情

類似語雀的評論:https://www.yuque.com/yuque/blog/sguhed

個性分割線

比如我想插入B站這種個性化的分割線

超鏈接卡片

比如我想插入知乎這樣的超鏈接卡片

如何插入表情?

我們從如何插入表情入手,一起看看怎么在Quill中插入自定義的內(nèi)容。

要在Quill中插入表情,只需要以下四步:

第一步:自定義工具欄按鈕
第二步:自定義Blot內(nèi)容EmojiBlot
第三步:在Quill注冊EmojiBlot
第四步:調(diào)用Quill的API插入表情

第一步:自定義工具欄按鈕

const quill = new Quill('#editor', {
  theme: 'snow',
  modules: {
    // 配置工具欄模塊
    toolbar: {
      container: [ …, [ 'emoji' ] ], // 增加一個按鈕
      handlers: {
        // 添加按鈕的處理邏輯
        emoji() {
          console.log('插入表情');
        }
      }
    },
  }
});

給工具欄按鈕增加圖標(biāo)

// 擴(kuò)展Quill內(nèi)置的icons配置
const icons = Quill.import('ui/icons');
icons.emoji = ‘<svg>…</svg>’; // 圖標(biāo)的svg可以從iconfont網(wǎng)站復(fù)制

效果如下:

工具欄上已經(jīng)多了一個表情的按鈕,并且能夠響應(yīng)鼠標(biāo)點(diǎn)擊事件,下一步就是要
編寫插入表情的具體邏輯,這涉及到Quill的自定義內(nèi)容相關(guān)的知識。

第二步:自定義Blot內(nèi)容EmojiBlot

Quill中的Blot就是一個普通的ES6 Class,由于表情和圖片的差別就在于:

Quill內(nèi)置的圖片格式不支持自定義寬高,而我們要插入的表情是需要特定的寬高的。

因此我們可以基于Quill內(nèi)置的image格式來擴(kuò)展。

emoji.ts

import Quill from 'quill';

const ImageBlot = Quill.import('formats/image');

// 擴(kuò)展Quill內(nèi)置的image格式
class EmojiBlot extends ImageBlot {
  static blotName = 'emoji'; // 定義自定義Blot的名字(必須全局唯一)
  static tagName = 'img'; // 自定義內(nèi)容的標(biāo)簽名

  // 創(chuàng)建自定義內(nèi)容的DOM節(jié)點(diǎn)
  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數(shù)據(jù)
  static value(node): any {
    return {
      url: node.getAttribute('src'),
       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);

第四步:調(diào)用Quill的API插入表情

EmojiBlot注冊到Quill中之后,Quill就能認(rèn)識它了,也就可以調(diào)用Quill的API將其插入到編輯器中。

emoji(): void {
  console.log(‘插入表情');
  // 獲取當(dāng)前光標(biāo)位置
  const index = this.quill.getSelection().index;
  // 在當(dāng)前光標(biāo)處插入emoji(blotName)
  this.quill.insertEmbed(index, 'emoji', {
    url: 'assets/emoji/good.png',
     '64px',
  });
},

效果圖

Demo源碼

源碼鏈接:https://gitee.com/kagol/quill-demo

也歡迎關(guān)注我們DevUI組件庫的官網(wǎng),了解更多有趣又實(shí)用的開源組件!

DevUI官網(wǎng):https://devui.design

Quill基本原理

最后講一講Quill的基本原理。

基本原理

使用Delta數(shù)據(jù)模型描述富文本內(nèi)容及其變化,以保證行為的可預(yù)測
通過Parchment對DOM進(jìn)行抽象,以保證平臺一致性
通過Mutation Observe監(jiān)聽DOM節(jié)點(diǎn)的變化,將DOM的更改同步到Delta數(shù)據(jù)模型中

Quill如何表達(dá)編輯器內(nèi)容?

Delta數(shù)據(jù)模型

通過Delta數(shù)據(jù)模型來描述富文本內(nèi)容及其變化

Delta 是JSON的一個子集,只包含一個 ops 屬性,它的值是一個對象數(shù)組,每個數(shù)組項(xiàng)代表對編輯器的一個操作(以編輯器初始狀態(tài)為空為基準(zhǔn))。

{
  "ops": [
    { "insert": "Hello " },
    { "insert": "World", "attributes": { "bold": true } },
    { "insert": "
" }
  ]
}

修改編輯器內(nèi)容

比如我們把加粗的"World"改成紅色的文字"World",這個動作用 Delta 描述如下:

{
  "ops": [
    { "retain": 6 },
    { "retain": 5, "attributes": { "color": "#ff0000" } }
  ]
}

意思是:保留編輯器最前面的6個字符,即保留"Hello "不動,保留之后的5個字符"World",并將這些字符設(shè)置為字體顏色為"#ff0000"。

刪除編輯器內(nèi)容

如果要刪除"World"呢?

{
  "ops": [
    { "retain": 6 },
    { "delete": 5 }
  ]
}

即:保留前面6個字符(’Hello ’),刪除之后的5個字符(’World’)

Quill如何渲染內(nèi)容?

渲染富文本內(nèi)容的基本原理:
遍歷Delta數(shù)組,將其中描述的內(nèi)容一個一個應(yīng)用(插入/格式化/刪除)到編輯器中。

詳情可參考DevUI專欄文章:

《Quill的內(nèi)容渲染機(jī)制》

Quill如何擴(kuò)展編輯器的能力?

擴(kuò)展Quill的方式:

通過自定義Blot格式來擴(kuò)展編輯器的內(nèi)容
通過自定義模塊來擴(kuò)展編輯器的功能

詳情可參考DevUI專欄文章:

《現(xiàn)代富文本編輯器Quill的模塊化機(jī)制》

THANK YOU!

總結(jié)

以上是生活随笔為你收集整理的Quill富文本编辑器的实践的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。