背景
? 目前市面上支持vue.js的富文本很多,例如:UEditor、wangEditor、Quill等等,这里也是经过了筛选和验证的,最开始选择的是Quill,后来发现使用了它的样式,对应需要展示的客户端也需要引用它的样式才能支持,耦合性太强、果断放弃、比较坑,其他的几款也尝试过wangEditor、UEditor。最终选择使用TinyMCE(插件丰富、界面美观、且对移动端兼容也还不错)。先上官网:https://www.tiny.cloud/docs/demo/full-featured/
相关依赖
"@tinymce/tinymce-vue": "^3.2.0",
"tinymce": "^5.2.0"
接入说明
中文文档
里面介绍了各种插件的使用,以及参数的配置,可以根据需要自行查阅。
http://tinymce.ax-z.cn/
组件汉化
http://tinymce.ax-z.cn/general/localize-your-language.php
导入插件
这里选择定义一个Js(import-all.js)一次性导入所有插件,也可以选择根据自己具体情况按需导入。
const importAll = requireContext => requireContext.keys().forEach(requireContext)
try {
importAll(require.context('../../../node_modules/tinymce/plugins', true))
} catch (err) {
console.log(err)
}
创建组件实例
<template>
<div>
<editor id="tinymceEditor"
:init="tinymceInit"
v-model="content"
:key="tinymceFlag">
</editor>
</div>
</template>
<script>
import tinymce from 'tinymce/tinymce'
import Editor from '@tinymce/tinymce-vue'
import 'tinymce/themes/silver'
import 'tinymce/icons/default'
import './import-all'
import { client, getFileNameUUID } from '@/utils/ali-oss'
import { getStsPermission } from '@/api/common/common'
export default {
name: 'Tinymce',
components: {
Editor
},
props: {
editorContent: {
type: String,
default: ''
},
height: {
type: Number,
default: 800
},
width: {
type: Number,
default: undefined
},
upload_url: {
type: String,
default: ''
},
showMenubar: {
type: Boolean,
default: true
},
toolbar: {
type: String,
default: ` undo redo
| formatselect
| bold italic strikethrough forecolor backcolor formatpainter
| link image | alignleft aligncenter alignright alignjustify
| numlist bullist outdent indent
| removeformat
| preview fullscreen code`
},
baseUrl: {
type: String,
default: ''
},
cdnOrigin: {
type: String,
default: 'https://static.v.xxxxxxxxx.com/system/resources/tinymce'
}
},
data() {
return {
tinymceFlag: 1,
tinymceInit: {},
content: ''
}
},
mounted() {
if (this.editorContent) {
this.content = this.editorContent
}
},
watch: {
content: {
handler() {
this.$emit('update:editorContent', this.content)
console.log('监听到数据变化')
}
},
editorContent: {
handler() {
this.content = this.editorContent
},
immediate: true
}
},
activated() {
this.tinymceFlag++
},
created() {
const _this = this
this.tinymceInit = {
language_url: `${this.cdnOrigin}/langs/zh_CN.js`,
language: 'zh_CN',
skin_url: `${this.cdnOrigin}/skins/ui/oxide`,
content_css: `${this.cdnOrigin}/skins/ui/oxide/content.css`,
height: this.height,
width: undefined,
browser_spellcheck: true,
branding: false,
elementpath: false,
statusbar: false,
paste_data_images: true,
image_dimensions: false,
menubar: this.showMenubar,
plugins: `print searchreplace autolink directionality visualblocks
visualchars template codesample charmap hr pagebreak nonbreaking anchor toc insertdatetime
wordcount textpattern help advlist table lists paste preview fullscreen image imagetools code link`,
toolbar: this.toolbar,
async images_upload_handler(blobInfo, success, failure) {
}
}
}
}
组件应用示例
这里支持获取编辑器富文本内容、纯文本内容,对应html、text动态绑定。
<el-form-item label="文章内容" prop="content">
<tinymce v-if="open"
:html-content.sync="form.contentHtml"
:text-content.sync="form.content">
</tinymce>
</el-form-item>
效果预览
编辑器窗口
上传图片效果
内容小窗口预览
遇到的问题及解决方案
在dialog(弹窗)层级、遮挡问题
- 找到依赖包下,如图位置,将其skins文件夹拷贝到本地或项目的pubilc下
- 将
skin.min.css 中的z-index的值由原本的1300修改到5000及以上,这里以5000为准
- 放在本地引用或者自行上传到云存储中引用即可解决遮挡问题。
预览效果宽度调整问题
通过浏览器调试发现,是由外层一个.tox .tox-dialog--width-lg 样式块限定了最大宽度,将其删掉或指定具体数值即可。
图片自动增加宽度不能自适应问题
在设置tinymceInit 初始化时,指定下方参数为禁用
image_dimensions: false
|