在Vue中使用CKEditor5富文本编辑器

在项目中遇到富文本编辑器需要实现粘贴图片的功能,使用场景:如用户在其他地方截图可以直接在富文本编辑器内粘贴。

找了一圈市面上开源免费的富文本编辑器,最后选中CKEditor。ckeditor  document build 版本默认是可以粘贴图片的, 其他build版本没有尝试。

安装: 有好几种build版本可以选,我选用的是@ckeditor/ckeditor5-build-decoupled-document ,官方也有基于Vue框架的使用方法,尝试了一下一直报错,作罢。

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

使用:我是把ckeditor封装成一个业务组件,方便在各个页面中使用

ckeditor上传文件一般需要自己写一个文件适配器

//ckeditor 富文本编辑器自定义上传图片adapter

//文件上传到七牛云 后端提供上传接口
import { qiniuInfo, uploadFile } from '@/api/common';

export default class UploadImageAdapter {
  constructor(loader) {
      this.loader = loader
      this.imgURL = "xxxxxx" //这个是图片域名
  }

  async upload() {
    //获取到用户上传的文件
    const img = await this.loader.file;

    const promise = new Promise(async (resolve, reject) => {
      const { data, status } = await qiniuInfo();
      if (status !== 200) reject(false)
      const formData = new FormData();
      //token为上传到七牛云所需要的
      formData.append('token', data.token);
      formData.append('file', img);
      const res = await uploadFile(formData).catch(() => {});
      if (res.status === 200) {
        //必须要要以 default: imgurl形式
        let response = {
          default: `${this.imgURL}${res.data.hash}` //图片全链接
        }
        resolve(response)
      } else {
        reject(false)
      }
    })
    return promise
  }


  abort() {
    //可以书写删除服务器图片的逻辑
  }
}





图片上传成功后 我们也许会有在编辑器中拖拽改变图片大小的需求,ckeditor中也是比较方便的,自带ImageResize插件,该插件在@ckeditor/ckeditor5-image 下面,安装该插件使用即可。

踩坑1:当我们使用build版本时,可能已经安装了@ckeditor/ckeditor5-image 但是没有引入ImageResize,这时我们再安装就会报错 ckeditor-duplicated-modules: Some CKEditor 5 modules are duplicated.
如何解决呢? 我的解决办法是 从github上clone一份对应版本没有打包的源代码,修改配置,重新打包,替换项目依赖中的build文件夹

git clone https://github.com/ckeditor/ckeditor5-editor-decoupled.git

//clone完成后在项目目录src下的ckeditor.js文件中

import ImageResize from '@ckeditor/ckeditor5-image/src/imageresize';

//把ImageResize加到DecoupledEditor.builtinPlugins中
//npm run build

在Vue中使用CKEditor5富文本编辑器_第1张图片

踩坑2: 由于我是模拟v-model的实现,在富文本内容发生变化的时候向外触发input事件并发送内容,富文本组件接受名为value的props,监听value值改变就调用setData方法,这会导致一个问题, 每次输入change都会被触发两次(一次是用户输入内容触发的,一次是value改变setData触发),不知到是不是这个原因,每次输入内容都会导致光标回到内容的开始位置。

解决方法:不在采用类似v-model方式,而是向外暴露两个方法 

//数据变化时把值保存到content字段
editor.model.document.on('change:data', () => {
    this.content = editor.getData();
 });

//向外暴露获取值和设置值的方法

getContent() {
  return this.content
}

setContent(val) {
  this.editor.setData(val)
}

//在使用页面
 

//获取值
let content = this.$refs.editor.getContent()

//设置值
this.$refs.editor.setContent(data)

 

你可能感兴趣的:(Vue)