CKEditor5

本篇博客是在react环境中封装的原生的CKEditor5,VUE环境也可以参考。

基本使用

安装依赖

npm install -- save @ckeditor/ckeditor5-build-classic
or
yarn add @ckeditor/ckeditor5-build-classic

完整的代码

import React, { Component } from 'react'
import ClassicEditor from '@ckeditor/ckeditor5-build-classic'

class DefaultCKEditor extends Component {

  componentDidMount() {
    this.init();
  }
  
  init = () => {
    ClassicEditor
      .create( document.querySelector( '#editor' ))
      .then( editor => {} )
      .catch( error => {} );
  }


  render() {
    return (
      <textarea name="content" id="editor">

      </textarea>
    )
  }
}

export default DefaultCKEditor

自定义工具栏

针对init()方法做调整

init = () => {
  ClassicEditor
    .create( document.querySelector( '#editor' ),{
      toolbar: [ 
        'heading', 
        '|', 
        'bold', 
        'italic', 
        'link', 
        'bulletedList', 
        'numberedList', 
        'blockQuote' 
      ],
    })
    .then( editor => {} )
    .catch( error => {} );
}

toolbar数组即为工具栏中的按钮,大多数开发者都想知道到底都有哪些按钮,
找了一大圈官方文档也没看到哪里罗列出所有的按钮。看源码吧!!!

这里的源码并不是node_modules下的源码

git clone -b stable git@github.com:ckeditor5-build-classic.git
是这个地址下未打包的源码
/src/editor.js 可以看到默认所有的工具栏的按钮名称
名称如下:

  • ‘heading’,
  • ‘bold’,
  • ‘italic’,
  • ‘link’,
  • ‘bulletedList’,
  • ‘numberedList’,
  • ‘imageUpload’,
  • ‘blockQuote’,
  • ‘insertTable’,
  • ‘mediaEmbed’,
  • ‘undo’,
  • ‘redo’

图片上传功能(上传到自己的服务器)

  • 图片上传功能需要自己实现一个上传适配器,官方文档有给出示例代码。

    上传适配器代码,一个js文件,起个名称叫MyUploadAdapter.js

export default class MyUploadAdapter {
  constructor( loader, url ) {
    // The FileLoader instance to use during the upload. It sounds scary but do not
    // worry — the loader will be passed into the adapter later on in this guide.
    this.loader = loader;


    // The upload URL in your server back-end. This is the address the XMLHttpRequest
    // will send the image data to.
    this.url = url;
    console.log(url);
  }

  // Starts the upload process.
  upload() {
    return new Promise( ( resolve, reject ) => {
      this._initRequest();
      this._initListeners( resolve, reject );
      this._sendRequest();
    } );
  }

  // Aborts the upload process.
  abort() {
    if ( this.xhr ) {
      this.xhr.abort();
    }
  }

  // Initializes the XMLHttpRequest object using the URL passed to the constructor.
  _initRequest() {
    const xhr = this.xhr = new XMLHttpRequest();

    // Note that your request may look different. It is up to you and your editor
    // integration to choose the right communication channel. This example uses
    // the POST request with JSON as a data structure but your configuration
    // could be different.
    xhr.open( 'POST', this.url, true );
    xhr.responseType = 'json';
  }

  // Initializes XMLHttpRequest listeners.
  _initListeners( resolve, reject ) {
    const xhr = this.xhr;
    const loader = this.loader;
    const genericErrorText = 'Couldn\'t upload file:' + ` ${ loader.file.name }.`;

    xhr.addEventListener( 'error', () => reject( genericErrorText ) );
    xhr.addEventListener( 'abort', () => reject() );
    xhr.addEventListener( 'load', () => {
      const response = xhr.response;

      // This example assumes the XHR server's "response" object will come with
      // an "error" which has its own "message" that can be passed to reject()
      // in the upload promise.
      //
      // Your integration may handle upload errors in a different way so make sure
      // it is done properly. The reject() function must be called when the upload fails.
      if ( !response || response.error ) {
        return reject( response && response.error ? response.error.message : genericErrorText );
      }

      // If the upload is successful, resolve the upload promise with an object containing
      // at least the "default" URL, pointing to the image on the server.
      // This URL will be used to display the image in the content. Learn more in the
      // UploadAdapter#upload documentation.

      // 上传成功
      // 根据自己后端的返回做相应的调整
      resolve( {
        default: response.url
      } );
    } );
    // Upload progress when it is supported. The FileLoader has the #uploadTotal and #uploaded
    // properties which are used e.g. to display the upload progress bar in the editor
    // user interface.
    if ( xhr.upload ) {
      xhr.upload.addEventListener( 'progress', evt => {
        if ( evt.lengthComputable ) {
          loader.uploadTotal = evt.total;
          loader.uploaded = evt.loaded;
        }
      } );
    }
  }

  // Prepares the data and sends the request.
  _sendRequest() {

    // Prepare the form data.
    const data = new FormData();
    // 修改上传的name参数
    data.append( 'fileName', this.loader.file );

    // Send the request.
    this.xhr.send( data );
  }

}

启用适配器


import React, { Component } from 'react'
import ClassicEditor from '@ckeditor/ckeditor5-build-classic'
import MyUploadAdapter from './MyUploadAdapter'

import './style.scss'

定义上传适配器
function MyCustomUploadAdapterPlugin( editor ) {
  editor.plugins.get( 'FileRepository' ).createUploadAdapter = ( loader ) => {
    // 第二个参数设置上传图片的地址
    return new MyUploadAdapter( loader, 'url***' );
  };
}

class DefaultCKEditor extends Component {

  componentDidMount() {
    let _this = this;
    ClassicEditor
      .create( document.querySelector( '#editor' ),{
        image: {
          toolbar: [
            'imageTextAlternative', '|',
            'imageStyle:alignLeft',
            'imageStyle:full',
            'imageStyle:alignRight'
          ],
          styles: [
            'full',
            'alignLeft',
            'alignRight'
          ]
        },
        extraPlugins: [ MyCustomUploadAdapterPlugin ]   // 添加上传适配器
      })
      .then( editor => {} )
      .catch( error => {} );
  }

  render() {
    return (
      <textarea name="content" id="editor">

      </textarea>
    )
  }
}

export default DefaultCKEditor

工具栏虽然可以自定义了,但是发现,工具栏的东西有点少,文本对齐,修改文字颜色和背景颜色都没有。

添加插件

插件可以增强工具栏的功能,下面演示如何添加文本对齐、字体颜色、字体背景插件。
  • 添加插件需要下载ckeditor的源码,在源码上安装插件包,再重新打包,替换node_modules下的包。
  • 下载源码:git clone -b stable git@github.com:ckeditor5-build-classic.git
  • 安装文本对齐插件 npm install --save-dev @ckeditor/ckeditor5-alignment
  • 安装字体颜色和背景插件(两个功能在同一个插件上) npm install --save-dev @ckeditor/ckeditor5-font
  • 在src/editor.js下启用插件,下面是完整代码 <-- add 表示添加的代码
/**
* @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/

// The editor creator to use.
import ClassicEditorBase from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';

import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials';
import UploadAdapter from '@ckeditor/ckeditor5-adapter-ckfinder/src/uploadadapter';
import Autoformat from '@ckeditor/ckeditor5-autoformat/src/autoformat';
import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';
import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';
import BlockQuote from '@ckeditor/ckeditor5-block-quote/src/blockquote';
import CKFinder from '@ckeditor/ckeditor5-ckfinder/src/ckfinder';
import EasyImage from '@ckeditor/ckeditor5-easy-image/src/easyimage';
import Heading from '@ckeditor/ckeditor5-heading/src/heading';
import Image from '@ckeditor/ckeditor5-image/src/image';
import ImageCaption from '@ckeditor/ckeditor5-image/src/imagecaption';
import ImageStyle from '@ckeditor/ckeditor5-image/src/imagestyle';
import ImageToolbar from '@ckeditor/ckeditor5-image/src/imagetoolbar';
import ImageUpload from '@ckeditor/ckeditor5-image/src/imageupload';
import Link from '@ckeditor/ckeditor5-link/src/link';
import List from '@ckeditor/ckeditor5-list/src/list';
import MediaEmbed from '@ckeditor/ckeditor5-media-embed/src/mediaembed';
import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
import PasteFromOffice from '@ckeditor/ckeditor5-paste-from-office/src/pastefromoffice';
import Table from '@ckeditor/ckeditor5-table/src/table';
import TableToolbar from '@ckeditor/ckeditor5-table/src/tabletoolbar';

import Alignment from '@ckeditor/ckeditor5-alignment/src/alignment';           <-- add
import Font from '@ckeditor/ckeditor5-font/src/font';                          <-- add

export default class ClassicEditor extends ClassicEditorBase {}

// Plugins to include in the build.
ClassicEditor.builtinPlugins = [
   Essentials,
   UploadAdapter,
   Autoformat,
   Bold,
   Italic,
   BlockQuote,
   CKFinder,
   EasyImage,
   Heading,
   Image,
   ImageCaption,
   ImageStyle,
   ImageToolbar,
   ImageUpload,
   Link,
   List,
   MediaEmbed,
   Paragraph,
   PasteFromOffice,
   Table,
   TableToolbar,
   Alignment,                         <-- add
   Font                               <-- add
];

// Editor configuration.
ClassicEditor.defaultConfig = {
   toolbar: {
   	items: [
   		'heading',
   		'|',
   		'fontcolor',                <-- add
   		'fontbackgroundcolor',      <-- add
   		'alignment',
   		'bold',
   		'italic',
   		'link',
   		'bulletedList',
   		'numberedList',
   		'imageUpload',
   		'blockQuote',
   		'insertTable',
   		'mediaEmbed',
   		'undo',
   		'redo'
   	]
   },
   image: {
   	toolbar: [
   		'imageStyle:full',
   		'imageStyle:side',
   		'|',
   		'imageTextAlternative'
   	]
   },
   table: {
   	contentToolbar: [
   		'tableColumn',
   		'tableRow',
   		'mergeTableCells'
   	]
   },
   // This value must be kept in sync with the language defined in webpack.config.js.
   language: 'zn'
};

最后 npm run build 将打包后的build文件夹 替换掉node_modules下 @ckeditor/cheditor5-build-classic下的build文件夹

Logo

前往低代码交流专区

更多推荐