CKEditor5 + vue2.0 自定義圖片上傳、highlight、字體等用法


 

  因業務需求,要在 vue2.0 的項目里使用富文本編輯器,經過調研多個編輯器,CKEditor5 支持 vue,遂采用。因 CKEditor5 文檔比較少,此處記錄下引用和一些基本用法。

 

CKEditor5官網

https://ckeditor.com/docs/ckeditor5/latest/builds/guides/overview.html

 

CKEditor5 引入

  有四種編輯器可供下載,根據自己的需求選擇,因為開發需求需要顏色筆,所以采用 Document editor。

  如果之前有用 Classic 版本的,在下載 Document 版本時需要 uninstall Classic,額,好像是句廢話,但是我用的時候 uninstall Classic好多次才卸載掉。

  

 

  1. 根據官網提示,采用 npm 引入CKEditor5,地址:https://ckeditor.com/ckeditor-5/download/。根據提示 copy 命令執行:

npm install --save @ckeditor/ckeditor5-build-decoupled-document

  

  2. router/index.js 引入 CKEditor

  

 

   3. 在使用的頁面引入,需要中文的可引入 zh-cn.js 文件

import DecoupledEditor from '@ckeditor/ckeditor5-build-decoupled-document'
import '@ckeditor/ckeditor5-build-decoupled-document/build/translations/zh-cn.js'

 

  4. html 頁面寫入 <ckedtior> 標簽

<ckeditor id="editor" :editor="editor" @ready="onReady" v-model="content" :config="editorConfig"></ckeditor>

說明:

  v-model = "content"  獲取編輯器里輸入的內容;

  :config = "editorCnfig" 需要配置的項;

   @ready = "onReady"  編輯器初始化

 

  5.  js 部分

import DecoupledEditor from '@ckeditor/ckeditor5-build-decoupled-document'
import '@ckeditor/ckeditor5-build-decoupled-document/build/translations/zh-cn.js'

DecoupledEditor
  .create(document.querySelector('#editor'), {
  }).then(editor => {
    // 打印所有的配置項
    // console.log('》》》》', Array.from( editor.ui.componentFactory.names() ) );
  }).catch(error => {
    console.error(error)
  })

export
default { data: () => ({ editor: DecoupledEditor, editorConfig: { toolbar: ['heading', 'fontSize', 'highlight', 'highlight:yellowMarker', 'highlight:greenMarker', 'highlight:pinkMarker', 'highlight:blueMarker', 'fontFamily', 'alignment', 'imageUpload', 'bold', 'italic', 'underline', 'imageStyle:full', 'imageStyle:alignLeft', 'imageStyle:alignRight', 'link', 'undo', 'redo'], fontSize: { options: [8, 9, 10, 11, 12, 'default', 14, 16, 18, 20, 22, 24, 26, 28, 36, 44, 48, 72], },
     highlight: {
      options: [
        { model: 'blackPen', class: 'pen-black', title: '黑色', color: 'var(--ck-highlight-pen-black)', type: 'pen' },
        { model: 'redPenPen', class: 'pen-red', title: '紅色', color: 'var(--ck-highlight-pen-red)', type: 'pen' },
     }
    },
    
ckfinder: {
      uploadUrl: `${store.getters.currentStack.baseURL}/ckeditor/upload`,
      // 后端處理上傳邏輯返回json數據,包括uploaded 上傳的字節數 和url兩個字段
     },
    }
  })
}
    

 

說明:

1. DecoupledEditor.create(document.querySelector('#editor'), {})此處代碼可省略,除非你想打印出所有的配置項。
2.
toolbar 配置工具欄
3. fontSize 字體 default 默認字體
4. highlight :配置字體顏色和高亮。詳細的寫法可參考:https://ckeditor.com/docs/ckeditor5/latest/features/highlight.html
(默認只有三四種顏色,谷歌搜“CKEditor5 highlight” ,第一條出來了,CKEditor 中文的文檔很少,不要抗拒英文文檔,逃離舒適區,也對自己說哈哈)

  

自定義圖片上傳插件問題

方法一:

  文中標紅的地方,是配置圖片上傳,只需要填寫上傳圖片的后台接口,注意,后台返回的字段必須包括 uploaded 上傳的字節數 和 url 兩個字段,不然一直會 alert 提示框報錯。

方法二:

  有些極端情況,上傳圖片的接口任何人都能訪問到,如果被盜用惡意上傳大量圖片,服務器的存儲空間和流量就會被擠爆,所以這個接口需要 token/cookie 校驗限制下。那么問題來了,如果需要傳遞 token 值,該怎么傳?這就需要自定義圖片上傳插件。推薦文章:https://www.jianshu.com/p/47e25447b771     里面有介紹如何自定義上傳圖片插件,但是有些部分講的不是特別清楚,當時也是看的雲里霧里。下面記錄下如何解決這個問題。

 

1、按照官網自定義上傳圖片插件的文檔,有兩篇文章可參考:

https://ckeditor.com/docs/ckeditor5/latest/framework/guides/deep-dive/upload-adapter.html

https://stackoverflow.com/questions/52873321/add-custom-headers-to-upload-image

 

  按照文檔,需要在 ClassicEditor.cteate() ,定義插件 MyCustomUploadAdapterPlugin ,在MyCustomUploadAdapterPlugin 插件里創建類 MyUploadAdapter,MyUploadAdapter 放在 <script> 標簽下面,寫法如下:(注意!onReady 里的這種寫法是錯的,正確的寫法是把綠色部分去掉,下面會講導致的 bug 及正確寫法)

<ckeditor id="editor" :editor="editor" v-model="content" @ready="onReady" :config="editorConfig"></ckeditor>

 

data: () => ({
  editor: DecoupledEditor
})
methods: {
        onReady( editor ) {
            DecoupledEditor .create( document.querySelector( '#editor' ), { extraPlugins: [ MyCustomUploadAdapterPlugin ], } ) .catch( error => { console.log( error ); }); function MyCustomUploadAdapterPlugin () {
                editor.plugins.get( 'FileRepository' ).createUploadAdapter = ( loader ) => {
                    return new MyUploadAdapter( loader );
                };
            }
        }
}

 

<script>
class MyUploadAdapter { constructor( loader ) { // Save Loader instance to update upload progress. this.loader = loader; } async upload() { const data = new FormData(); data.append('typeOption', 'upload_image'); data.append('upload', await this.loader.file); return new Promise((resolve, reject) => { axios({ url: `api/xxxx/ckeditor/upload`, method: 'post', data, headers: { 'Authorization': 'Bearer tokenxxxxxxxxxxxxxxxxxxx' // 此處為你定義的token 值(Bearer token 接口認證方式) }, withCredentials: true // true 為不允許帶 token, false 為允許,可能會遇到跨域報錯:Error: Network Error 彈窗提示(感謝@ big_yellow 指正) }).then(res => { var resData = res.data; resData.default = resData.url; resolve(resData); }).catch(error => { reject(error) }); }); } }
</script>

  

  我查到的文檔里是沒有上段代碼兩處標紅的地方 async await (ES6 用法),導致 console.log 錯誤,同事誤打誤撞加上 async await ,沒有報錯,具體原因還不太清楚,可能是 DOM 還未加載出來導致的,歡迎大家指正。

  寫到這里,頁面可以正常加載,並可傳遞 token 值使用圖片上傳功能,但是,編輯器默認內容會顯示 @ 符號,

 console.log(11111, document.getElementById('editor').childNodes[0]) 打印出這個值為:<br data-cke-filler>,或下圖 <p>@</p>,

嘗試使用清除 DOM 把 “@” 刪除,但是編輯器試圖刪除不存在的 DOM 節點時崩潰,導致頁面卡死。

報錯討論參考文檔: https://www.bountysource.com/issues/52514130-editor-crashes-trying-to-delete-dom-nodes-that-do-not-exist

 

 

  解決方法如下:運用 editor.setData() 設置編輯器初始值。

 

 現在說下正確的自定義圖片上傳插件在 @onReady 里寫法:

onReady( editor ) {
    // 自定義上傳圖片插件
    editor.plugins.get( 'FileRepository' ).createUploadAdapter = ( loader ) => {
         return new MyUploadAdapter( loader );
     };  
 }

  解釋:@onReady 的作用跟 DecoupledEditor.create( document.querySelector( '#editor' ), {}) 作用一樣,導致報錯。

 

 

設置字體樣式:

有的用戶瀏覽器不支持的字體樣式,需要下載字體包,並在 css 里設置 @font-face 

@font-face {
    font-family: 'KaiTi';
    src: url('../fonts/KaiTi.ttf');
    font-family: 'SimHei';
    src: url('../fonts/SimHei.ttf');
    font-family: 'SimSun';
    src: url('../fonts/SimSun.ttf');
    font-weight: normal;
    font-style: normal;
}

  

    data: () => ({
        title: '',
        type: 'news',
        content: '',
        publish_at: '',
        editor: DecoupledEditor,
        editorConfig: {
            language: 'zh-cn',
            toolbar: ['heading', 'fontSize', 'fontFamily', 'redo', 'insertTable'],
            fontSize: {
                options: [ 12, 'default', 14, 16, 18, 20, 22, 24, 26, 28, 36, 44, 48, 72],
            },
            fontFamily: {
                options: [
                    '宋體',
                    '黑體',
                    '楷體',
                    '微軟雅黑',
                ]
            },
    })

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM