富文本編輯器 quill.js 開發(二): 升級與表格功能

前言

在富文本編輯器場景中, 表格是一種不可忽視的功能, 但是在當前 quill.js 的正式版本(1.x)中, 卻不支持此功能

所以本文承接上文 鏈接, 來講述下 quill.js 升級到 2.x 的問題以及添加表格功能

爲什麼需要升級

在目前的 1.x 版本中並不支持表格的元素, 而我們想要這個功能的話
一是升級, 通過官方的支持來添加, 二是我們自己開發, 但是這樣的成本過大了

當前官方進度

image

根據 npm 官方包的發佈時間來看, 2.x 版本處於開發的停滯階段

所以本次我們就以當前官方版本 1.3.7 爲基礎, 再手動添加 2.0.0-dev.4 的代碼

手動進行 2.0 升級

目前我們使用的是 react-quill 倉庫, 我們要將其源碼複製下來, 同時也將 quill2.x 源碼克隆, 將其作爲依賴

最終維護的文件格式爲:

├── quill
│   ├── assets
│   ├── blots
│   ├── core
│   ├── core.ts
│   ├── formats
│   ├── modules
│   ├── quill.ts
│   ├── themes
│   └── ui
├── react-quill
│   ├── index.tsx
│   └── quill.snow.less

詳情可查看倉庫: https://github.com/Grewer/react-quill2

差異點:

  • CSS 樣式問題(原有的 li, ol 不再通過標籤來區分, 而是用節點的類型)
  • 同樣地代碼塊 pre 也是使用了 div 代替
  • 添加了一些新的 formats
  • 不再支持 IE11
  • setContents API 的變更
    editor.clipboard.convert 的使用從原有的 editor.clipboard.convert(value) 改爲 editor.clipboard.convert({html: string, text: string}, formats: Record<string, unknown> = {} )
  • 其他的一些 API 變更(和表格功能關係不大)

更加詳細的變更可查看: https://github.com/quilljs/quill/blob/develop/docs/guides/upgrading-to-2-0.md

現有表格功能調研

在升級 2.0 之後, 我們的編輯器已經擁有了表格功能, 但是沒有擴展, 比如插入一行, 插入一列, 刪除等等, 這些是用戶常用的操作
所以我們需要一個插件來擴展

GitHub 上搜索關鍵詞 quill + table 之後出現的結果:

目前 star 大於 10, 且是正常庫(非測試庫, 類似於這種), 最近 2-3 年有更新的, 結果只有 2 個, 最後我們對這 2 個庫來進行調研

  1. https://github.com/volser/quill-table-ui
  2. https://github.com/soccerloway/quill-better-table

這兩個庫都是有自己對應的 demo, 可以點擊查看:

  1. quill-table-ui
  2. quill-better-table

目前看這兩個倉庫基本都能實現較好的表格方案

本文選擇了 quill-table-ui 作爲接入方案, 大夥如果喜歡 quill-better-table 也可以考慮自己來了接入

擴展表格功能

新增文件 modules/table.ts :
這裏就簡單展示一下主要邏輯


export default class TableUI {
    menuItems: MenuItem[] = [
        {
            title: 'Insert column right',
            icon: iconAddColRight,
            handler: () => {
                if (
                    !(this.options.maxRowCount > 0) ||
                    this.getColCount() < this.options.maxRowCount
                ) {
                    this.table.insertColumnRight();
                }
            },
        },
        // 省略
        // 這裏的數據是點擊一個表格, 顯示的菜單, 新增行列, 刪除行列
    ];
    
    
        toggleClickHandler = (e) => {
        // 控制菜單顯示
    };
    
    showMenu() {
        // 菜單顯示的具體 dom 操作
    }
    
    hideMenu() {
        // 刪除菜單的 dom 操作
    }
    
    createMenuItem(item: MenuItem) {
        // 創建菜單時, 構建菜單結構
        const node = document.createElement('div');
        node.classList.add('ql-table-menu__item');
    
        node.addEventListener(
            'click',
            (e) => {
                e.preventDefault();
                e.stopPropagation();
                this.quill.focus();
                item.handler();
                this.hideMenu();
                this.detectButton(this.quill.getSelection());
            },
            false
        );
        return node;
    }
    
    
    
    destroy() {
        // 刪除時, 去掉引用對象, 監聽等等操作
    }
}

注意點
此額外組件原本就有錯誤, 我們需要修改他的依賴包:
import { positionElements } from 'positioning'; 替換爲 import positions from 'position.js';

同時替換原有的 positionElements 邏輯即可

在註冊之後, 我們就正式調用對應的 API, 來創建表格:

// 註冊
Quill.register({ 'modules/tableUI': TableUI }, true);

function insertTable() {
    const quill = editorRef.current?.editor
    if(quill){
        quill.focus();
        const table = quill.getModule('table');
        table.insertTable(3, 2);
    }
}

添加效果動圖演示:

image

這裏再展示一下, 我們添加的表格插件, 包括了正常的插入/刪除行列等等功能:

image

在完成添加功能之後, 我們還需要一個添加自定義長寬的表格功能

這裏我們用數組來創建一個 10*10 的方格即可, 最後在外層添加代理:

<div
  className={`${preClass}-box`}
  onMouseMove={this.mouseoverHandle}
  onClick={this.clickHandle}
>
  {this.cellArr.map((row, rowIndex) => {
    return row.map((col, colIndex) => {
      return (
        <div
          data-position={`${rowIndex},${colIndex}`}
          className={classNames(this.cellClass, {
            active: rowIndex <= activeRow && colIndex <= activeCol,
          })}
          key={`${rowIndex}${colIndex}`}
        />
      );
    });
  })}

最後點擊時, 獲取長寬, 調用 table.insertTable(x, y); api 即可

至此, 表格功能基本已經全部完成

結語

本文中的 demo 都是簡化版本, 樣式也沒有調整, 如果要在生產中使用的話還需進一步的優化

目前來說, 因爲 quill 一直卡在 2.0@dev 中, 後面的升級都需要自己來維護
他的功能和 api 是非常豐富的, 可以滿足 90% 以上的業務需求, 但是後續開發新功能的話也會花費一番精力, 大家可以酌情使用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章