相对功能较全的富文本功能,文件,图片上传功能实现,富文本内容较长时,建议内容上传接口以文件形式保存
"@tinymce/tinymce-vue": "^3.2.8",
"tinymce": "^5.7.0",
```
<template>
<div class="tinymce">
<!-- <h1>tinymce</h1> -->
<editor id="tinymce" v-model="tinymceHtml" :init="init" />
</div>
</template>
<script>
import tinymce from 'tinymce/tinymce'
import 'tinymce/themes/silver/theme'
import Editor from '@tinymce/tinymce-vue'
import 'tinymce/icons/default' // 引入编辑器图标icon,不引入则不显示对应图标
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',
// 声明最原始的tinymce组件
components: { Editor },
props: {
// tinyvalue首先在父组件中定义,用于向本子组件mytinymce发送数据
// 然后在这里声明,用于本子组件接收父组件数据
tinyvalue: {
type: String,
default: ''
},
richtextid: {
type: String,
required: true
}
},
data() {
return {
// 子组件的数据变量,默认未父组件传递过来的数据
tinymceHtml: this.tinyvalue,
// tinymce默认配置参数,含插件,请注意插件路径,如果错误容易保unexpect token ','之类错误
init: {
relative_urls: true,
language_url: '../../tinymce/zh_CN.js',
language: 'zh_CN',
skin_url: '../../tinymce/skins/ui/oxide-dark',
height: 500,
plugins:
// 'link lists image code table colorpicker textcolor wordcount contextmenu',
'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,
paste_data_images: true,
file_picker_types: 'file',
file_picker_callback: (callback, value, meta) => {
// 文件分类
var filetype = '.pdf, .txt, .zip, .rar, .7z, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .mp3, .mp4'
var _this = this
var input = document.createElement('input')
input.setAttribute('type', 'file')
input.setAttribute('accept', filetype)
input.click()
input.onchange = function() {
var file = this.files[0]
const params = new FormData()
params.append('file', file)
params.append('resourceId', _this.richtextid)
const config = {
headers: {
'Content-Type': 'multipart/form-data'
}
}
// // aixo的声明在全局main.js中,这里不粘贴了
_this.$https
.post(`${process.env.VUE_APP_BASE_API}/richText/uploadRichEnclFile`, params, config)
.then((res) => {
if (res.data.code === 200) {
callback(res.data.data, { text: file.name, title: file.name })
} else {
// failure('上传失败')
}
})
.catch(() => {
// failure('上传出错,服务器开小差了呢')
})
}
},
// 增加下面的images_upload_handler对象,能够支持上传图片到服务器
images_upload_handler: (blobInfo, success, failure) => {
// console.log(blobInfo.blob())
if (blobInfo.blob().size / 1024 / 1024 > 5) {
failure('上传失败,图片大小请控制在 5M 以内')
} else {
const params = new FormData()
params.append('file', blobInfo.blob())
params.append('resourceId', this.richtextid)
const config = {
headers: {
'Content-Type': 'multipart/form-data'
}
}
// aixo的声明在全局main.js中,这里不粘贴了
this.$https
.post(`${process.env.VUE_APP_BASE_API}/richText/uploadImg`, params, config)
.then((res) => {
if (res.data.code === 200) {
// const resp = res.data.data
// const url = resp.schemeIpPort + resp.dir + '/' + resp.subDir + '/' + resp.filename
const url = res.data.data
success(url)
// 上传成功,在成功函数里填入图片路径
// var img = `<img alt="" src="${url}" />`
// this.tinymceHtml += img
} else {
failure('上传失败')
}
})
.catch(() => {
failure('上传出错,服务器开小差了呢')
})
}
}
}
}
},
watch: {
// 监听内容变化,用于辅助父子组件之间的通讯
tinyvalue(newValue) {
// tinyvalue是父组件代理人,父组件值一旦变化,推送给子组件
this.tinymceHtml = newValue
},
tinymceHtml(newValue) {
// tinymceHtml是子组件的值,如果改变,直接反馈给父组件
// tinymceinput是父组件中的用于接收子组件的事件(名称写死,用于后面调用)
this.$emit('tinymceinput', newValue)
}
},
mounted() {
// 初始化加载配置项
tinymce.init({})
},
methods: {}
}
</script>
```