Vue 集成 CKEditor5 踩坑记录
最近项目中有编辑文章的需求,需要用到富文本编辑器,在查看个各种编辑器之后,发现只有 CKEditor5 的功能是比较符合需求的。然而,在使用过程中发现,坑是真的多… 这里记录下填坑经历,希望能对其他小伙伴有帮助。CKEditor5 介绍编辑器种类CKEditor5 有 5 种常用编辑器,分别是:ClassicBallonBallon BlockInlineDocument具体区别可以参照官网:ht
最近项目中有编辑文章的需求,需要用到富文本编辑器,在查看个各种编辑器之后,发现只有 CKEditor5 的功能是比较符合需求的。然而,在使用过程中发现,坑是真的多… 这里记录下填坑经历,希望能对其他小伙伴有帮助。
CKEditor5 介绍
编辑器种类
CKEditor5 有 5 种常用编辑器,分别是:
- Classic
- Ballon
- Ballon Block
- Inline
- 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 的基本功能了。
常规操作
- 获取内容:
editor.getData()
- 设置内容:
editor.setData(val)
踩坑记录
坑一:图片更改大小
当时就是看中了 CKEditor5 的更改图片大小功能来的,怎么自己一顿操作之后没有这个功能了呢,原来是因为 Doucment 编辑器中原本就没有更改图片大小的功能。嗨,这好说啊,你没有,我给你加上不就完了。于是我看着官网,安装了 @ckeditor/ckeditor5-image
,在配置文件中引入,最后满怀期待的跑项目,嗯?居然报错了。
他说我 CKEditor5 中的一些模块重复了,后来查阅了无数资料后才发现,这是个巨坑!!原来官方在 build
Document 的时候,虽然安装了 ckeditor5-image
,但是,他没引入 ckeditor5-image
下的 imageresize
功能,这时候如果我们自己安装,他就会重复。
没办法,需求在这压着呢,为了使他有这个功能,我只能去改他的源码,引入 imageresize
,重新打包并替换掉 node_modules
里的 build
,流程如下:
- 找到源码:https://github.com/ckeditor/ckeditor5-build-decoupled-document
- 进入文件夹后
npm install
下载imageresize
- 打开项目
src
下的ckeditor.js
文件,加上imageresize
- npm run build 打包
- 覆盖
node_modules
里面的文件
好了,现在图片可以改变大小了,但是还有一个问题,不能每次从 gitLab 上拉项目,npm i
之后都要去改源码吧,于是我又在项目中新建了一个 plugin
文件夹,将重新打包后的 build
放了进去,并在 README.md 中做出了重点强调。
至此,CKEditor5
的第一大坑,算是跨过去了。
坑二:图片布局失效
情况是这样的,当我调整好图片的布局(左、右浮动)后,将得到的 html
字符串放到页面中渲染的时候,我发现本来已经调整好的图片布局竟然失效了。后来发现,CKEditor5
的做法是利用 js
将 css
引入到所在项目(页面)中,并在图片上添加 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);
}
更多推荐
所有评论(0)