CKEditor5的入門使用(react)

沒有前言绊诲,開始講解劣挫。

使用環(huán)境: 基于react的antd-pro框架橡淑,這部分受antd的影響較泻咔(僅部分表標簽)蕊梧。CKEditor5的document 12.1.0版本.

1、 安裝與引入

cnpm install @ckeditor/ckeditor5-build-decoupled-document
可根據(jù)需求安裝對應的主題插件:

npm install --save @ckeditor/ckeditor5-build-classic
# Or:
npm install --save @ckeditor/ckeditor5-build-inline
# Or:
npm install --save @ckeditor/ckeditor5-build-balloon
# Or:
npm install --save @ckeditor/ckeditor5-build-balloon-block
# Or:
npm install --save @ckeditor/ckeditor5-build-decoupled-document

index.js

import React, { PureComponent, Fragment } from 'react';
import { Spin } from 'antd'
... ...
// 自定義圖片上傳功能
import MyUploadAdapter from './UploadAdapter';
// 引入ckeditor5插件
import DecoupledEditor from '@ckeditor/ckeditor5-build-decoupled-document';
// 引入中文包
import '@ckeditor/ckeditor5-build-classic/build/translations/zh-cn';
... ...
export default class Rich_text_editor extends PureComponent {
  ... ...
}

2人芽、初始化

export default class Rich_text_editor extends PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      loading: false,
    }
    this.editor = {};
  }

  componentDidMount() {
    // 接受傳入的初始內(nèi)容
    let { value = "" } = this.props;
    this.init(value);
  }

  init(init_value){
     // 自定圖片上傳組件
    const MyCustomUploadAdapterPlugin = ( editor ) => {
      editor.plugins.get( 'FileRepository' ).createUploadAdapter = ( loader ) => {
        // 抓取圖片上傳狀態(tài)
        loader.uploadType = this.uploadType.bind(this)

        return new MyUploadAdapter( loader );
      };
    }
    
    // 初始化組件
    DecoupledEditor
    .create(
      // 文本內(nèi)容所在標簽
      document.querySelector( '#editor' ),
      {
        // 設置語言為中文望几,需引入中文包,謝謝評論區(qū)`小籠包不是包`指正萤厅。
        language : 'zh-cn',
        // 設置初始值
        initialData: init_value,
        // 加載圖片上傳組件
        extraPlugins: [ MyCustomUploadAdapterPlugin ],
        // 移除組件
        removePlugins: [ 'Link', 'MediaEmbed' ],
        // 自定字號列表
        fontSize: {options: [10,12,14,16,18,20,24]},
        // 自定字體列表
        fontFamily:{
          options: [
            'default',
            'Arial, Helvetica, sans-serif',
            'Courier New, Courier, monospace',
            'Georgia, serif',
            'Lucida Sans Unicode, Lucida Grande, sans-serif',
            'Tahoma, Geneva, sans-serif',
            'Times New Roman, Times, serif',
            'Trebuchet MS, Helvetica, sans-serif',
            'Verdana, Geneva, sans-serif',
        ]},
        // 自定heading列表
        heading: {
          options: [
            { model: 'paragraph', title: '正文', class: 'ck-heading_paragraph' },
            { model: 'heading1', view: 'h1', title: '標題1', class: 'ck-heading_heading1' },
            { model: 'heading2', view: 'h2', title: '標題2', class: 'ck-heading_heading2' },
            { model: 'heading3', view: 'h3', title: '標題3', class: 'ck-heading_heading3' },
            { model: 'heading4', view: 'h4', title: '標題4', class: 'ck-heading_heading4' },
          ]
        },
        // 自定圖片toolbar內(nèi)容
        image: {
          toolbar: [ 'imageTextAlternative' ]
        }
        // 還有其他的橄抹,有需要請查看官方文檔,格式基本差不多
      }
    )
    .then( editor => {
      // 選擇toolbar所在標簽
      const toolbarContainer = document.querySelector( '#toolbar-container' );
      toolbarContainer.appendChild( editor.ui.view.toolbar.element );
   
      this.editor = editor;
      // 內(nèi)容變更時觸發(fā)惕味,獲取內(nèi)容楼誓,因為我是寫完直接下一步的。
      editor.model.document.on('change:data', (e)=>{
          let richText = editor.getData();
          ... ... 
      })
    })
    .catch( error => {
      console.error( error );
    });
  }

  // 圖片上傳狀態(tài)
  uploadType(type){
    this.setState({
      loading: type
    })
  }

  render () {
    return (
        <Spin spinning={this.state.loading}>
          <div className={stylei.editorElem} >
            <div id="toolbar-container" className={stylei.container}></div>
            <div id="editor" className={stylei.content} >
              <p>請輸入文本內(nèi)容...</p>
            </div>
          </div>
        </Spin>
    )
  }
}

以上按照官方文檔也能寫個差不多名挥,主要是圖片上傳部分


3疟羹、圖片上傳(fetch方式)

uploadType.js

// 封裝的fetch上傳組件
import { imageUpload } from '@/services/api';

export default class MyUploadAdapter {
  constructor( loader ) {
    this.loader = loader;
  }

  upload () {

    /*
       注意此處的uploadType方法。
      這是我在index,js中 自己定義了一個uploadType函數(shù),并放在了 
      loader中一起傳了過來:
      const MyCustomUploadAdapterPlugin = ( editor ) => {
        editor.plugins.get( 'FileRepository' ).createUploadAdapter = ( loader ) => {
          // 抓取圖片上傳狀態(tài)
          loader.uploadType = this.uploadType.bind(this)
          return new MyUploadAdapter( loader );
        };
      }
    */
    // 傳入開始狀態(tài)
    this.loader.uploadType(true)
    return this.loader.file
      .then( file => new Promise( async ( resolve, reject ) => {
        let userMess = localStorage.getItem('userMess');
        if(userMess){
          // 這一部分都是普通的數(shù)據(jù)處理榄融,根據(jù)需求自己修改
          const { pucid } = JSON.parse(userMess);
          var data = new FormData();
          data.append("picture", file);
          data.append("pucid", pucid);
          let res = await imageUpload(data);

          // 傳入結(jié)束狀態(tài)
          this.loader.uploadType(false)
          if(res){
            let { message, status, data={} } = res;
            if(status == 200){

             /* 此格式為固定格式参淫,default表示為默認圖片,
                另外還有其他格式請參考官方文檔愧杯,這部分比較容易理解涎才,不做贅述
                參考此處:https://ckeditor.com/docs/ckeditor5/latest/framework/guides/deep-dive/upload-adapter.html#responsive-images-and-srcset-attribute
            */
              resolve( { default: data.pictureUrl  } );
            } else { reject(message) }
          } else { reject('圖片上傳失敗') }
        } else { reject('獲取用戶信息失敗,請重新登錄') }
      })
    );
  }

  // Aborts the upload process.
  abort() {
    console.log('暫停上傳')
  }
}

uploadType寫完之后力九,按照"初始化"部分引入即可耍铜。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市跌前,隨后出現(xiàn)的幾起案子棕兼,更是在濱河造成了極大的恐慌,老刑警劉巖抵乓,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件伴挚,死亡現(xiàn)場離奇詭異,居然都是意外死亡臂寝,警方通過查閱死者的電腦和手機章鲤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來咆贬,“玉大人败徊,你說我怎么就攤上這事√投校” “怎么了皱蹦?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長眷蜈。 經(jīng)常有香客問我沪哺,道長,這世上最難降的妖魔是什么酌儒? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任辜妓,我火速辦了婚禮,結(jié)果婚禮上忌怎,老公的妹妹穿的比我還像新娘籍滴。我一直安慰自己,他們只是感情好榴啸,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布孽惰。 她就那樣靜靜地躺著,像睡著了一般鸥印。 火紅的嫁衣襯著肌膚如雪勋功。 梳的紋絲不亂的頭發(fā)上坦报,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機與錄音狂鞋,去河邊找鬼片择。 笑死,一個胖子當著我的面吹牛要销,可吹牛的內(nèi)容都是我干的构回。 我是一名探鬼主播夏块,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼疏咐,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了脐供?” 一聲冷哼從身側(cè)響起浑塞,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎政己,沒想到半個月后酌壕,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡歇由,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年卵牍,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片沦泌。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡糊昙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出谢谦,到底是詐尸還是另有隱情释牺,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布回挽,位于F島的核電站没咙,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏千劈。R本人自食惡果不足惜祭刚,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一督禽、第九天 我趴在偏房一處隱蔽的房頂上張望薇正。 院中可真熱鬧,春花似錦腾供、人聲如沸憔古。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鸿市。三九已至锯梁,卻和暖如春即碗,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背陌凳。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工剥懒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人合敦。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓初橘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親充岛。 傳聞我的和親對象是個殘疾皇子保檐,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容