精彩文章免费看

CKEditor5的入门使用(react)

没有前言,开始讲解。

使用环境: 基于react的antd-pro框架,这部分受antd的影响较小(仅部分表标签)。 CKEditor5 的document 12.1.0版本.

1、 安装与引入

cnpm install @ckeditor/ckeditor5-build-decoupled-document
可根据需求安装对应的主题插件:

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() {
    // 接受传入的初始内容
    let { value = "" } = this.props;
    this.init(value);
  init(init_value){
     // 自定图片上传组件
    const MyCustomUploadAdapterPlugin = ( editor ) => {
      editor.plugins.get( 'FileRepository' ).createUploadAdapter = ( loader ) => {
        // 抓取图片上传状态
        loader.uploadType = this.uploadType.bind(this)
        return new MyUploadAdapter( loader );
    // 初始化组件
    DecoupledEditor
    .create(
      // 文本内容所在标签
      document.querySelector( '#editor' ),
        // 设置语言为中文,需引入中文包,谢谢评论区`小笼包不是包`指正。
        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内容
        image: {
          toolbar: [ 'imageTextAlternative' ]
        // 还有其他的,有需要请查看官方文档,格式基本差不多
    .then( editor => {
      // 选择toolbar所在标签
      const toolbarContainer = document.querySelector( '#toolbar-container' );
      toolbarContainer.appendChild( editor.ui.view.toolbar.element );
      this.editor = editor;
      // 内容变更时触发,获取内容,因为我是写完直接下一步的。
      editor.model.document.on('change:data', (e)=>{
          let richText = editor.getData();
          ... ... 
    .catch( error => {
      console.error( error );
  // 图片上传状态
  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>请输入文本内容...</p>
        </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函数,并放在了 
      loader中一起传了过来:
      const MyCustomUploadAdapterPlugin = ( editor ) => {
        editor.plugins.get( 'FileRepository' ).createUploadAdapter = ( loader ) => {
          // 抓取图片上传状态
          loader.uploadType = this.uploadType.bind(this)
          return new MyUploadAdapter( loader );
    // 传入开始状态
    this.loader.uploadType(true)
    return this.loader.file
      .then( file => new Promise( async ( resolve, reject ) => {
        let userMess = localStorage.getItem('userMess');
        if(userMess){
          // 这一部分都是普通的数据处理,根据需求自己修改
          const { pucid } = JSON.parse(userMess);
          var data = new FormData();
          data.append("picture", file);
          data.append("pucid", pucid);
          let res = await imageUpload(data);
          // 传入结束状态
          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写完之后,按照"初始化"部分引入即可。

最后编辑于:2019-06-01 16:45