300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 在Vue中使用CKEditor5富文本编辑器

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

时间:2023-08-27 10:08:35

相关推荐

在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 = loaderthis.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() {//可以书写删除服务器图片的逻辑}}

<template><div><!-- 工具栏容器 --><div id="toolbar-container"></div><!-- 编辑器容器 --><div id="editor"></div></div></template><script>import CKEditor from '@ckeditor/ckeditor5-build-decoupled-document';//中文包import '@ckeditor/ckeditor5-build-decoupled-document/build/translations/zh-cn';//上传图片所需的适配器import UploadImageAdapter from '@/jslibs/UploadImageAdapter';export default {name: 'ckeditor',props: {value: {required: true,}},data() {return {editor: null,}},mounted(){this.initCKEditor()},methods:{initCKEditor() {CKEditor.create(document.querySelector('#editor'), toolbar: ['heading','|','bold','italic','Underline','fontSize','numberedList','bulletedList','blockQuote','|','alignment:left','alignment:right','alignment:center','alignment:justify','|','imageUpload','Link','|','undo', //撤销'redo',//重做],heading: {options: [{ model: 'paragraph', title: '段落', class: 'ck-heading_paragraph' },{ model: 'heading6', view: 'h6', title: '标题6', class: 'ck-heading_heading6' },{ model: 'heading5', view: 'h5', title: '标题5', class: 'ck-heading_heading5' },{ model: 'heading4', view: 'h4', title: '标题4', class: 'ck-heading_heading4' },{ model: 'heading3', view: 'h3', title: '标题3', class: 'ck-heading_heading3' },{ model: 'heading2', view: 'h2', title: '标题2', class: 'ck-heading_heading2' },{ model: 'heading1', view: 'h1', title: '标题1', class: 'ck-heading_heading1' }]},language: 'zh-cn'fontSize: {options: ['default',14, 16, 18, 20, 22, 24]}}).then(editor => {const toolbarContainer = document.querySelector('#toolbar-container');toolbarContainer.appendChild(editor.ui.view.toolbar.element);this.editor = editor //将编辑器保存起来,用来随时获取编辑器中的内容等,执行一些操作//使用图片上传适配器editor.plugins.get('FileRepository').createUploadAdapter = ( loader ) => {return new UploadImageAdapter(loader)};editor.model.document.on('change:data', () => {//把富文本编辑器获取到的内容传出去this.$emit('input', editor.getData())});//编辑的时候设置富文本编辑器的内容editor.setData(this.value);}).catch(error => {console.error(error);});},}}</script><style lang="less" scoped>//设置编辑器内容区域最小高度#editor {min-height: 380px;border: 1px solid #c4c4c4;}/deep/.ck-content {min-height: 380px;}</style>

图片上传成功后 我们也许会有在编辑器中拖拽改变图片大小的需求,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 /ckeditor/ckeditor5-editor-decoupled.git//clone完成后在项目目录src下的ckeditor.js文件中import ImageResize from '@ckeditor/ckeditor5-image/src/imageresize';//把ImageResize加到DecoupledEditor.builtinPlugins中//npm run build

踩坑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)}//在使用页面<ck-editor ref="editor"></ck-editor> //获取值let content = this.$refs.editor.getContent()//设置值this.$refs.editor.setContent(data)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。