700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 富文本编辑器:ckeditor(使用ckeditor4-vue)

富文本编辑器:ckeditor(使用ckeditor4-vue)

时间:2018-10-10 09:28:59

相关推荐

富文本编辑器:ckeditor(使用ckeditor4-vue)

最近,vue项目中使用了富文本编辑器,经过反复研究,选择了ckeditor,ckeditor分为4和5,我们选的4,网上中文的相关资料比较少,总结一下使用的经验。

官方网站:/ckeditor-4/,里面有下载,文档等,Add-ons里面还有额外的plugin。

构建vue项目

首先使用vue create ckeditor_example_1创建vue项目,因为我们的控件使用了element-ui,因此进入项目先下载一下控件npm install --save element-ui

使用ckeditor4-vue构建基本富文本编辑器

在vue项目中使用ckeditor4有两种方式,一种是自己去官网下载ckeditor的包,解压放在项目里面,另一个就是使用他们包装好的ckeditor4-vue包,这里,我们就使用了该包,使用命令npm install --save ckeditor4-vue下载包。

然后,创建编辑器文件Editor.vue:

<template><div><ckeditor ref="editor" :config="config" v-model="editorData"@namespaceloaded="onNamespaceLoaded" @ready="onEditorReady"></ckeditor></div></template><script>export default {name: 'Editor',data () {return {editorData: ''}},props: {config: {type: Object,default: () => {}},ready: {type: Function,default: () => {}}},methods: {onNamespaceLoaded (CKEDITOR) {console.log(CKEDITOR)},onEditorReady (editor) {this.ready(editor)}}}</script><style scoped></style>

这样一个基本的ckeditor就构建好了,在想要使用的地方引用该文件即可<editor ref="editor"></editor>

分析一下<ckeditor ref="editor" :config="config" v-model="editorData" @namespaceloaded="onNamespaceLoaded" @ready="onEditorReady"></ckeditor>这行代码,需要注意的是editorData是编辑器里面的文本内容;config是编辑器的配置文件,如果基础的编辑器可以满足你的要求的话,可以不配置config,使用该对象,你可以在一个项目中配置多个不同的editor;onNamespaceLoaded是处理全局变量CKEDITOR完成的事件,也就是说,这之后才可以使用window.CKEDITOR变量;onEditorReady处理编辑器对象构建完成的事件,也就是说,在此之后,当前的编辑器对象才可以使用,比如进行插入文本等操作。

上图是默认的编辑器的样式(背景色我自己改了),下面说一下它的额外功能。

额外功能

修改配置文件

config里面有很多配置项,我们可以直接修改CKEDITOR.config影响所有的editor,也可以给单独的editor配置config。

/docs/ckeditor4/latest/api/CKEDITOR_config.html

下面我们说一下,基本的editor遇到的问题,以及如何通过配置config解决

1.从其他地方复制HTML页面,粘贴,只保留了文字

在配置文件里面添加allowedContent: truepasteFilter: null去除文本的过滤功能。

2.编辑器的高度太低,不符合预期

在配置文件里面添加height: 500配置编辑器的高度

3.想要指定语言为英语

在配置文件里面添加language: 'en'配置编辑器的语言

4.想要自定义编辑器的toolbar

在配置文件里面添加toolbar的配置项,内容格式如下:

toolbar: [{name: 'code',items: ['Source']},{name: 'basicstyles',items: [ 'Styles', '-', 'Bold', 'Italic', 'Strike', 'Underline', 'TextColor', 'BGColor', 'Font', 'FontSize' ]},{name: 'styles',items: ['RemoveFormat']},{name: 'insert',items: [ 'Table', "SpecialChar", "HorizontalRule", 'CodeSnippet']},'/',{name: 'paragraph',items: ['Format', 'NumberedList', 'BulletedList','-', 'Indent', 'Outdent', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight' ]},{name: 'links',items: ['Link', 'Unlink']},{name: 'document',items: ['Undo', 'Redo']}]

其中,{}里面是分组,’/'表示换行,items是具体的button,具体button的名字,可以自己去看源码找,反正我没有在文档里面找到介绍所有toolbar button的内容。

注意,我这里的配置使用了很多额外的plugin,如果你没有配置extraPlugins的话,直接使用可能会出错。这里使用的额外的plugin有colorbutton, colordialog, dialog, indentblock, indentlist, justify, font, codesnippet,这些plugin不需要自己定义,可以直接在extraPlugins里面配置就可以使用了。

自定义plugin

下面介绍一下,如果想要自己定义一个插件的话,应该怎么做。

ckeditor自己带的image插件,我觉得用起来太麻烦,所以自己定义了一个图片上传的插件。插件代码如下:

import img from '../../assets/img.png'export default {init () {window.CKEDITOR.plugins.add('myImage', {icons:"myImage",init: function(editor){editor.addCommand("myImage", {exec: function( editor ) {let file = document.createElement('input')file.type = 'file'file.accept = 'image/*'file.addEventListener('change', () => {const reader = new FileReader();reader.readAsDataURL(file.files[0]);reader.onload = () => {editor.insertHtml(`<img src="${reader.result}"/>`)};reader.onerror = error => {console.error(error)};})file.click()}});editor.ui.addButton('MyImage',{label:'Insert Image',icon: img,command:'myImage'});}})}}

插件的路径是/src/components/plugins/myImage.js,图标使用的assets里面的img.png(我直接扒的ckeditor的图标,然后自己剪裁的,和他的image图标一模一样)。window.CKEDITOR.plugins.add('myImage'这行代码是添加插件的主代码,myImage是我的插件名;editor.addCommand添加一个命令,点击button的时候执行它,执行的方法就是exec;editor.ui.addButton添加我们自己的button,里面的command配置之前定义的command即可,点击button的时候就执行该命令。上面的代码做的就是,点击添加的imagebutton的时候,打开上传文件的dialog,然后你选一张图片,把它转成base64插入editor之中。你可以修改代码,选择将图片上传到你自己的服务器,然后,插入图片的url。

好吧,插件写好了,但是,还没有调用,我们应该在哪里调用呢?可以看到我们使用了window.CKEDITOR变量,所以需要该变量生成完成之后,再调用,推荐放到onNamespaceLoaded里面调用。

import myImage from './plugins/myImage'export default {name: 'Editor',methods: {onNamespaceLoaded (CKEDITOR) {console.log(CKEDITOR)myImage.init()}}}

plugin注册好了,那么我们的toolbar里面直接就有了吗?并不是,你还需要配置config文件的extraPlugins,把注册的plugin加上,配置toolbar,把注册的button加上,至于toolbar的位置,你也可以写plugin定义的时候指定,具体可以自己看文档。

config : {extraPlugins: 'myImage',toolbar: [{name: 'insert',items: [ 'MyImage', 'Table', "SpecialChar", "HorizontalRule", 'CodeSnippet']}]}

至此,自定义的插件就好了。启动之后,发现,button的图片显示不出来,经过调查,vue小图片打包成base64,这样的话,ckeditor显示不出来,修改vue的配置文件

vue.config.js(没有的话,自己添加,这是新版的vue,旧版的话,可能是修改自己的webpack配置文件),取消小文件打包成base64的配置。

module.exports = {// ......devServer: {disableHostCheck: true,port: 59999},chainWebpack: config => {config.module.rule('images').use('url-loader').loader('url-loader').tap(options => Object.assign(options, {limit: 0 }))},configureWebpack: {plugins: []}}

这只是一个简单的自定义插件,没有使用dialog,也没有使用panel。

ckeditor定义dialog的话,配置很麻烦,而且样式和我们的项目不一致,改样式也很麻烦。因此,我迂回了一下,使用了自己的dialog,下面简单介绍一下,怎么使用自己的dialog。

自带的table的dialog:

我自定义的插入div的dialog:

这是我的使用自己的dialog的插件的定义:

import d from '../../assets/div.png'export default {init () {window.CKEDITOR.plugins.add('myDialog', {icons:"myDialog",init: function(editor){editor.addCommand("myDialog", {exec: function( editor ) {console.log(editor)editor.dialog.show()}});editor.ui.addButton('MyDialog',{label:'Show Dialog',icon: d,command:'myDialog'});}})}}

我们定义了一个button,点击的时候执行代码editor.dialog.show(),其中的dialog就是我们自定义的dialog,它有个方法叫show,就是显示dialog。那么,这个dialog究竟是在哪里加入editor这个对象的呢?editor对象是ckeditor的内置对象,并没有我们的dialog这个对象,还记得之前定义的时候的@ready="onEditorReady"吗?是的,我们可以定义在onEditorReady方法里面。

onEditorReady (editor) {editor.dialog = this.$refs.dialog}

其中,this.$refs.dialog就是我们自定义的dialog对象。至于dialog的具体定义,你可以自己创建一个dialog.vue文件,自定义。

监听editor的事件

onEditorReady (editor) {//监听paste事件,处理copy/paste图片editor.on( 'paste', async evt => {if(evt.data.dataTransfer.getFilesCount() > 0) {evt.data.dataValue = ''let res = await this.handleTransferImage(evt)if(res){editor.insertHtml(`<img src="${res.url}"/>`)}}})//监听key的事件,实现tab的时候,调用indent命令editor.on( 'key', function( event ) {let keycode = event.data.keyCode;if( keycode == 9 ) {event.cancel();editor.execCommand('indent')}})},

其他的基础功能

//自定义ckeditor的背景色和字体颜色onNamespaceLoaded (CKEDITOR) {CKEDITOR.addCss(`body{background: #7b8b6f;color: white;}`)},//设置editor的html文本内容setContent (data) {this.editorData = data//this.$refs.editor.instance.setData(data)},//获取editor的html文本内容getContent () {//return this.$refs.editor.instance.getData()return this.editorData},//在鼠标处插入指定的htmlinsertHtml (html) {this.$refs.editor.instance.insertHtml(html)},//执行editor内置的commandexecCommand (command) {this.$refs.editor.instance.execCommand(command)},//将editor设为readonly的setReadonly (readonly) {this.$refs.editor.instance.setReadOnly(readonly)},//判断是否是readonly的isReadonly () {return this.$refs.editor.instance.readOnly},//disable/enable指定的commandsetDisable(command, disable) {if(disable) {this.$refs.mands[command].enable()} else {this.$refs.mands[command].disable()}},//获取指定的command,比如'source'getCommand (command) {return this.$refs.mands[command]}

遇到的问题

1.官网的Add-ons里面的插件不能直接使用,必须自己下载源码然后改写

2.使用的都是cdn的资源,公司网络问题,速度特别慢,初始化需要10s左右,难以接受

由于公司网络问题,没有办法使用ckeditor的cdn,最后,放弃了使用ckeditor4-vue,自己去官网下载了ckeditor的资源包,解压放到项目里面使用了,下次介绍一下,这种用法要怎么做。

代码仓库:/gaograce/ckeditor-vue-example1.git

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