Vue项目中使用Tinymce5富文本编辑器

目录
  1. 1. 1. 安装及引用
  2. 2. 2. 初始化编辑器(记录出现的问题和解决方案)
  3. 3. 3. 配置
  4. 4. 4. 定制
  5. 5. Vue中封装使用tinymce富文本编辑器
    1. 5.1. 准备工作
    2. 5.2. 组件封装

项目使用vue-cli 3.x版本,tinymce5

1. 安装及引用

注:只安装tinymce-vue不可以,还需安装tinymce,否则会报错

1
2
3
4
5
npm install tinymce
npm install @tinymce/tinymce-vue

import tinymce from 'tinymce/tinymce'
import Editor from '@tinymce/tinymce-vue'

2. 初始化编辑器(记录出现的问题和解决方案)

按示例初始化发现编辑器不显示,报“theme.js:1 Uncaught SyntaxError: Unexpected token <”这个错,需要手动引入tinymce主题,在init({})方法里加theme: 'silver',没用。
import 'tinymce/themes/silver/theme'
不报错了但是编辑器还是不显示,继续研究,发现还需要定义“skin_url”,在init({})里加skin: "oxide"没用。先在public目录下新建一个文件夹命名为tinymce,然后在node_modules里找到tinymce的skin包,复制到public/tinymce里,在创建tinymce时的init({})里添加下面这行代码:
skin_url: '/tinymce/skins/ui/oxide',

3. 配置

  • 一些常用的配置属性

    1
    2
    3
    4
    5
    6
    browser_spellcheck: true, // 拼写检查
    branding: false, // 去水印
    elementpath: false, //禁用编辑器底部的状态栏
    statusbar: false, // 隐藏编辑器底部的状态栏
    paste_data_images: true, // 允许粘贴图像
    menubar: false, // 隐藏最上方menu
  • plugins
    使用某个插件需要先引入这个插件,例:

    1
    2
    3
    4
    import 'tinymce/plugins/fullscreen'
    import 'tinymce/plugins/preview'

    plugins: 'fullscreen preview'
  • toolbar
    可以使用|给工具栏分组,把某一类功能划分成一组,例:
    toolbar: 'bold italic underline | alignleft aligncenter alignright'

4. 定制

将语言改为中文,步骤:
1.在官网下载语言包https://www.tiny.cloud/get-tiny/language-packages/
2.把下载的语言包放到之前新建的tinymce文件夹里
3.初始化时添加以下代码

1
2
language_url: `/tinymce/langs/zh_CN.js`,
language: 'zh_CN',

在tinymce5工具栏添加自定义功能按钮

1
2
3
4
5
6
7
8
9
10
11
12
13
this.tinymceInit = {
...
toolbar: 'imageUpload',
setup: (editor) => {
editor.ui.registry.addButton('imageUpload', {
tooltip: '插入图片',
icon: 'image',
onAction: () => {

}
})
}
}

关于tinymce完整的例子在我的github项目里https://github.com/Inspiration1/asteroid


Vue中封装使用tinymce富文本编辑器

准备工作

安装tinymce-vue
npm install @tinymce/tinymce-vue -S
下载tinymce
npm install tinymce -S

下载tinymce完成后在node_modules中找到tinymce/skins目录,将其复制到static\tinymce目录下面;
下载中文语言包;
下载完成后将其解压到static\tinymce目录下面;

组件封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<template>
<div>
<editor id="tinymce" v-model="value" :init="init"></editor>
</div>
</template>

<script>
//引入基础文件:
import tinymce from 'tinymce/tinymce'
import Editor from '@tinymce/tinymce-vue'
import 'tinymce/themes/silver'
import 'tinymce/plugins/image'// 插入上传图片插件
export default {
name: "tinymce",
components:{
Editor
},
props:{
curValue:{
type:String,
default:''
}
},
data(){
return{
init:{
language_url: '/tinymce/langs/zh_CN.js',// 语言包的路径
language: 'zh_CN',//语言
skin_url: '/tinymce/skins/ui/oxide',// skin路径
height: 400,//编辑器高度
branding: false,//是否禁用“Powered by TinyMCE”
menubar: false,//顶部菜单栏显示
elementpath: false, //禁用编辑器底部的状态栏
paste_data_images: true,// 允许粘贴图像
plugins:'image',
toolbar:['formatselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | lists image media table | removeformat'],
images_upload_handler: (blobInfo, success, failure) => {
let formData = new FormData();
formData.append('folder', 'editor/img');
formData.append('upfile', blobInfo.blob(), blobInfo.filename());
this.$api.uploadFile(formData).then(response => {
if(response.code==1){
let fileArr = response.data.files[0].url;
success(fileArr);
}
})
.catch(()=>{
failure("上传失败")
})
}
},
value: this.curValue
}
},
mounted() {
tinymce.init({})
},
watch: {
curValue(newValue) {
this.value = newValue
},
value(newValue) {
this.$emit('input', newValue)
}
}
}
</script>

页面中使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<Tinymce :curValue="initContent" @input="newContent"></Tinymce>

//引入组件
import Tinymce from '@/components/tinymce/tinymce'
export default {
components:{
Tinymce
},
data() {
return {
initContent:''//默认值
}
},
methods: {
newContent(val){
console.log(val);//获取输入内容
}
}
}