在Vue项⽬中引⼊tinymce富⽂本编辑器项⽬中原本使⽤的富⽂本编辑器是,这是⼀个很轻量、简洁编辑器
但是公司的业务升级,想要⼀个功能更全⾯的编辑器,我了好久,⽬前常见的编辑器有这些:
:百度前端的开源项⽬,功能强⼤,基于 jQuery,但已经没有再维护,⽽且限定了后端代码,修改起来⽐较费劲
:微型,易⽤,⼩⽽美,只是 Bootstrap +
:功能强⼤,代码简洁,需要配置后台,⽽且好久没见更新了
:轻量、简洁、易⽤,但是升级到 3.x 之后,不便于定制化开发。不过作者很勤奋,⼴义上和我是⼀家⼈,打个call
:本⾝功能不多,不过可以⾃⾏扩展,api 也很好懂,如果能看懂英⽂的话...
:没深⼊研究,UI挺漂亮,也是⼀款⼩⽽美的编辑器,可是我需要⼤的
在有这么参考的情况下,我最终还是选择了这个不搞⿊科技连官⽹都打不开的编辑器(简直是⾃讨苦吃),主要因为两点:
1. GitHub 上星星很多,功能也齐全;
2. 唯⼀⼀个从 word 粘贴过来还能保持绝⼤部分格式的编辑器;
3. 不需要后端⼈员扫码改接⼝,前后端分离;
4. 说好的两点呢!
注意:这篇博客仅适⽤于 Tinymce 4.x
除了 tinymce 之外,也是⼀个⼤⽽全的富⽂本编辑器
但 CK5 门槛较⾼,有兴趣的可以看这篇⽂章
⼀、资源下载
tinymce 官⽅为 vue 项⽬提供了⼀个组件
npm install @tinymce/tinymce-vue -S
在 vscode、webstorm 的终端运⾏这段代码可能会报错,最好使⽤操作系统⾃带的命令⾏⼯具
如果有购买 tinymce 的服务,可以参考 tinymce-vue 的说明,通过 api-key 直接使⽤ tinymce
像我这样没购买的,还是要⽼⽼实实下载 tinymce
npm install tinymce -S
安装之后,在 node_modules 中到 tinymce/skins ⽬录,然后将 skins ⽬录拷贝到 static ⽬录下
// 如果是使⽤ vue-cli 3.x 构建的 typescript 项⽬,就放到 public ⽬录下,⽂中所有 static ⽬录相关都这样处理
tinymce 默认是英⽂界⾯,所以还需要下载⼀个中⽂(记得⽤科学的办法来访问!)
然后将这个语⾔包放到 static ⽬录下,为了结构清晰,我包了⼀层 tinymce ⽬录
⼆、初始化
在页⾯中引⼊以下⽂件
import tinymce from'tinymce/tinymce'
import 'tinymce/themes/modern/theme'
import Editor from'@tinymce/tinymce-vue'
经评论区提醒,如果不到  import 'tinymce/themes/modern/theme'
可以替换成 import 'tinymce/themes/silver/theme'
tinymce-vue 是⼀个组件,需要在 components 中注册,然后直接使⽤
<Editor id="tinymce" v-model="tinymceHtml" :init="editorInit"></Editor>
这⾥的 init 是 tinymce 初始化配置项,后⾯会讲到⼀些关键的 api,完整 api 可以参考
编辑器需要⼀个 skin 才能正常⼯作,所以要设置⼀个 skin_url 指向之前复制出来的 skin ⽂件
editorInit: {
language_url: '/static/tinymce/zh_CN.js',
language: 'zh_CN',
skin_url: '/static/tinymce/skins/lightgray',
height: 300
}
// vue-cli 3.x 创建的 typescript 项⽬,将 url 中的 static 去掉,即 skin_url: '/tinymce/skins/lightgray'
同时在 mounted 中也需要初始化⼀次:
如果在这⾥传⼊上⾯的 init 对象,并不能⽣效,但什么参数都不传也会报错,所以这⾥传⼊⼀个空对象
有朋友反映这⾥有可能出现以下报错
这是因为 init 参数地址错误,请核对下 init 参数中的⼏个路径是否正确
如果参数⽆误,可以先删除 language_url 和 language 再试
三、扩展插件
完成了上⾯的初始化之后,就已经能正常运⾏编辑器了,但只有⼀些基本功能
tinymce 通过添加插件的⽅式来添加功能
⽐如要添加⼀个上传图⽚的功能,就需要⽤到 image 插件,添加超链接需要⽤到 link 插件
同时还需要在页⾯引⼊这些插件:
添加了插件之后,默认会在⼯具栏 toolbar 上添加对应的功能按钮,toolbar 也可以⾃定义
贴⼀下完整的组件代码:
<template>
<div class='tinymce'>
<h1>tinymce</h1>
<editor id='tinymce' v-model='tinymceHtml' :init='init'></editor>
<div v-html='tinymceHtml'></div>
</div>
</template>
<script>
import tinymce from'tinymce/tinymce'
import 'tinymce/themes/modern/theme'
import Editor from'@tinymce/tinymce-vue'
import 'tinymce/plugins/image'
import 'tinymce/plugins/link'
import 'tinymce/plugins/code'
import 'tinymce/plugins/table'
import 'tinymce/plugins/lists'
import 'tinymce/plugins/contextmenu'
import 'tinymce/plugins/wordcount'
import 'tinymce/plugins/colorpicker'
import 'tinymce/plugins/textcolor'
export default {
name: 'tinymce',
data () {
return {
tinymceHtml: '请输⼊内容',
init: {
language_url: '/static/tinymce/zh_CN.js',
language: 'zh_CN',
skin_url: '/static/tinymce/skins/lightgray',
什么是富文本编辑器height: 300,
plugins: 'link lists image code table colorpicker textcolor wordcount contextmenu',
toolbar:
'bold italic underline strikethrough | fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist | outdent indent blockquote | undo redo | link unlink image code | removeformat        branding: false
}
}
},
mounted () {
tinymce.init({})
},
components: {Editor}
}
</script>
四、上传图⽚
tinymce 提供了 images_upload_url 等 api 让⽤户配置上传图⽚的相关参数
但为了在不⿇烦后端的前提下适配⾃家的项⽬,还是得⽤ images_upload_handler 来⾃定义⼀个上传⽅法
这个⽅法会提供三个参数:blobInfo, success, failure
其中 blobinfo 是⼀个对象,包含上传⽂件的信息:
success 和 failure 是函数,上传成功的时候向 success 传⼊⼀个图⽚地址,失败的时候向 failure 传⼊报错信息
贴⼀下我⾃⼰的上传⽅法,使⽤了 axios 发送请求
handleImgUpload (blobInfo, success, failure) {
let formdata = new FormData()
formdata.set('upload_file', blobInfo.blob())
axios.post('/api/upload', formdata).then(res => {
success(res.data.data.src)
}).catch(res => {
failure('error')
})
}