最近项目中有编辑文章的需求,需要用到富文本编辑器,在查看个各种编辑器之后,发现只有 CKEditor5 的功能是比较符合需求的。然而,在使用过程中发现,坑是真的多… 这里记录下填坑经历,希望能对其他小伙伴有帮助。

CKEditor5 介绍

编辑器种类

CKEditor5 有 5 种常用编辑器,分别是:

  1. Classic
  2. Ballon
  3. Ballon Block
  4. Inline
  5. Document

具体区别可以参照官网:https://ckeditor.com/ckeditor-5/demo/
以上 5 种编辑器都是官方打包好的,功能范围已经限定好了(这是之后的一个大坑),如果你需要一些特殊的功能,也可以自定义一个编辑器。不过,自定义的编辑器默认会下载成一个压缩包,我习惯使用 npm ,所以这里我选择的是 Document。

下载

CKEditor5 提供三种下载方式,npm、zip 或 CDN,大家可根据需求习惯自行选择。之前也说过了,我习惯使用npm,所以就以 npm 为例。

npm 安装命令:

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

开始使用

基本功能

因为我要自定义工具栏内容,所以我提取了一个 ckeditor.js 工具文件(注意:虽然官方规定了 Document 编辑器有哪些功能,使用者还是可以规定工具栏种是否要显示这些功能图标的。也就是说,我有的,你可以不用;但是我没有的,你一定用不了):

ckeditor.js

// 第一步:引入 CKEditor5
import CKEditor from "@ckeditor/ckeditor5-build-decoupled-document";
// 第二步:自定义工具栏内容
CKEditor.defaultConfig = {
  language: "zh-cn",
  toolbar: [
    "bold",
    "italic",
    "strikethrough",
    "underline",
    "|",
    "fontFamily",
    "fontSize",
    "fontColor",
    "fontBackgroundColor",
    "|",
    "numberedList",
    "bulletedList",
    "alignment",
    "|",
    "codeblock",
    "blockQuote",
    "link",
    "imageUpload",
    "|",
    "undo",
    "redo",
  ],
  // 配置可用的字体大小
  fontSize: {
    options: [12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38],
  },
  // 配置图片功能栏
  image: {
    toolbar: [
      "imageTextAlternative",
      "imageStyle:full",
      "imageStyle:side",
      "imageStyle:alignLeft",
      "imageStyle:alignCenter",
      "imageStyle:alignRight",
    ],
    styles: ["full", "side", "alignLeft", "alignCenter", "alignRight"],
  },
}

// 第三步:声明上传图片的构造函数
class UploadAdapter {
  constructor(loader) {
    this.loader = loader;
  }

  upload() {
    return new Promise(resolve => {
      let file = this.loader.file;
      let url = URL.createObjectURL(file)
      
      resolve({
        default: url,
      });
    });
  }
}
// 第四步:导出 CKEditor 和 UploadAdapter
export { CKEditor, UploadAdapter }

定义好工具栏后,我们就可以在 .vue 文件中真正的使用 CKEditor 了。
首先,需要在 html 部分定义好编辑框部分和工具栏部分的容器:

template 部分

<template>
  	<div class="editor">
	  	<div id="richEditorBar"></div>
	
		<div id="editor"></div>
  	</div>
</template>

script 部分

import { CKEditor, UploadAdapter } from "@/utils/ckeditor";

export default {
  	data() {
		return {
			editor: null,
			editorVal: '<p>默认值..</p>'
		}
	},
	mounted() {
		this.createEditor()
	},
	methods: {
		createEditor() {
			CKEditor.create($("#editor")[0]).then(editor => {
				// 绑定图片上传插件
		        editor
		        	.plugins
		        	.get("FileRepository")
		        	.createUploadAdapter = loader => new UploadAdapter(loader);
				// 定义工具栏
		        const toolbarContainer = $("#richEditorBar")[0];
		        toolbarContainer.appendChild(editor.ui.view.toolbar.element);
		        // 赋值
		        editor.setData(this.editorVal);
		        this.editor = editor;
		      })
		}
	}
}

这样,就可以使用 CKEditor5 的基本功能了。

常规操作
  1. 获取内容:editor.getData()
  2. 设置内容:editor.setData(val)

踩坑记录

坑一:图片更改大小

当时就是看中了 CKEditor5 的更改图片大小功能来的,怎么自己一顿操作之后没有这个功能了呢,原来是因为 Doucment 编辑器中原本就没有更改图片大小的功能。嗨,这好说啊,你没有,我给你加上不就完了。于是我看着官网,安装了 @ckeditor/ckeditor5-image ,在配置文件中引入,最后满怀期待的跑项目,嗯?居然报错了。
在这里插入图片描述
他说我 CKEditor5 中的一些模块重复了,后来查阅了无数资料后才发现,这是个巨坑!!原来官方在 build Document 的时候,虽然安装了 ckeditor5-image ,但是,他没引入 ckeditor5-image 下的 imageresize 功能,这时候如果我们自己安装,他就会重复。

没办法,需求在这压着呢,为了使他有这个功能,我只能去改他的源码,引入 imageresize ,重新打包并替换掉 node_modules 里的 build ,流程如下:

  1. 找到源码:https://github.com/ckeditor/ckeditor5-build-decoupled-document
  2. 进入文件夹后 npm install 下载 imageresize
  3. 打开项目 src 下的 ckeditor.js 文件,加上 imageresize

在这里插入图片描述

  1. npm run build 打包
  2. 覆盖 node_modules 里面的文件

好了,现在图片可以改变大小了,但是还有一个问题,不能每次从 gitLab 上拉项目,npm i 之后都要去改源码吧,于是我又在项目中新建了一个 plugin 文件夹,将重新打包后的 build 放了进去,并在 README.md 中做出了重点强调。

至此,CKEditor5 的第一大坑,算是跨过去了。

坑二:图片布局失效

情况是这样的,当我调整好图片的布局(左、右浮动)后,将得到的 html 字符串放到页面中渲染的时候,我发现本来已经调整好的图片布局竟然失效了。后来发现,CKEditor5 的做法是利用 jscss 引入到所在项目(页面)中,并在图片上添加 class 来实现图片的布局样式 …

那问题就来了,我用编辑器的目的就是获取 html 字符串并拿到其他页面中去做展示,总不能我哪些页面要用到这些字符串,就要在哪些页面上引入编辑器吧。

最后只能是将 CKEditor5 中的这些 class 整理出来,自己去配置样式:

img {
    max-width: 100%;
}
 
.image_resized {
    max-width: 100%;
}

.image-style-side {
    float: right;
    margin-left: var(--ck-image-style-spacing);
}

.image-style-align-left {
    float: left;
    margin-right: var(--ck-image-style-spacing);
}

.image-style-align-center {
    margin-left: auto;
    margin-right: auto;
    text-align: center;
}

.image-style-align-right {
    float: right;
    margin-left: var(--ck-image-style-spacing);
}
Logo

前往低代码交流专区

更多推荐