建议一定要给selector, 如果容器是同一个,有可能会造成打开一个空的编辑器,里面却会有之前打开过的内容.
我这边直接封装一个父级容器,对它的id进行赋值,其值是时间戳
<div :id="selectorId">
<editor v-if="!reloading" v-model="myValue" :init="init" :disabled="disabled" @onClick="onClick">
</editor>
</div>
selectorId: new Date().getTime(), //避免重复使用同一个div编辑器
this.$emit('change', newValue)
tinymce有输入,改变两种模式.
通俗的说,输入就是,人为的直接在编辑器内输入,改变就是通过代码直接添加.
有了这个了解,就可以解决这个问题
//当triggerChange时true时,进行代码侵入,当时false时,用户输入模式
watch: {
value(newValue) {
this.myValue = (newValue == null ? '' : newValue)
},
myValue(newValue) {
if (this.triggerChange) {
this.$emit('change', newValue)
} else {
this.$emit('input', newValue)
}
}
}
解决方法: 写一个reload的方法,监听 当他的父级是 a-modal时,执行reload
<div :id="selectorId">
<editor v-if="!reloading" v-model="myValue" :init="init" :disabled="disabled" @onClick="onClick">
</editor>
</div>
reloading: false,
methods: {
reload() {
this.reloading = true
this.$nextTick(() => this.reloading = false)
},
initATabsChangeAutoReload() {
// 获取父级
let modal = getVmParentByName(this,'AModal')
if(modal){
console.log("tinymce reload!")
this.reload();
}
},
}
mounted() {
this.initATabsChangeAutoReload()
},
<template>
<div :id="selectorId">
<editor v-if="!reloading" v-model="myValue" :init="init" :disabled="disabled" @onClick="onClick">
</editor>
</div>
</template>
<script>
import tinymce from 'tinymce/tinymce'
import Editor from '@tinymce/tinymce-vue'
import {
setStore,
getStore,
clearStore
} from "@/utils/storage"
import "tinymce/icons/default/icons";
import 'tinymce/themes/silver/theme'
import 'tinymce/plugins/table'
import 'tinymce/plugins/lists'
// import 'tinymce/plugins/contextmenu'
import 'tinymce/plugins/wordcount'
// import 'tinymce/plugins/textcolor'
import 'tinymce/plugins/fullscreen'
// import 'tinymce/icons/default'
import 'tinymce/plugins/advlist'
import 'tinymce/plugins/preview'
import 'tinymce/plugins/charmap'
import 'tinymce/plugins/autosave'
import {
uploadAction,
getFileAccessHttpUrl
} from '@/api/manage'
import {
getVmParentByName
} from '@/utils/util'
export default {
components: {
Editor
},
name: "JEditor",
props: {
height: {
type: Number,
required: false,
default: 500
},
width: {
type: Number,
required: false,
default: 500
},
value: {
type: String,
required: false
},
triggerChange: {
type: Boolean,
default: false,
required: false
},
disabled: {
type: Boolean,
default: false
},
plugins: {
type: [String, Array],
default: 'lists advlist charmap indent2em table wordcount preview fullscreen autosave'
},
toolbar: {
type: [String, Array],
default: 'undo redo | formatselect removeformat | charmap bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | lists advlist table | preview restoredraft fullscreen',
branding: false
}
},
data() {
return {
//初始化配置
init: {
language_url: '/tinymce/langs/zh_CN.js',
language: 'zh_CN',
skin_url: '/tinymce/skins/lightgray',
height: this.height,
width: this.width,
plugins: this.plugins,
statusbar: false, //隐藏状态栏
toolbar: this.toolbar,
branding: false,
menubar: true,
autosave_restore_when_empty: true,
autosave_interval: "20s",
autosave_retention: "10080m",
toolbar_drawer: "floating",
images_upload_handler: (blobInfo, success) => {
let formData = new FormData()
formData.append('file', blobInfo.blob(), blobInfo.filename());
formData.append('biz', "jeditor");
formData.append("jeditor", "1");
uploadAction(window._CONFIG['domianURL'] + "/sys/common/upload", formData).then((res) => {
if (res.success) {
if (res.message == 'local') {
const img = 'data:image/jpeg;base64,' + blobInfo.base64()
success(img)
} else {
let img = getFileAccessHttpUrl(res.message)
success(img)
}
}
})
}
},
selectorId: new Date().getTime(), //避免重复使用同一个div编辑器
myValue: this.value,
reloading: false,
}
},
mounted() {
this.initATabsChangeAutoReload()
},
methods: {
reload() {
this.reloading = true
this.$nextTick(() => this.reloading = false)
},
onClick(e) {
this.$emit('onClick', e, tinymce)
},
//可以添加一些自己的自定义事件,如清空内容
clear() {
this.myValue = ''
},
/**
* 自动判断父级是否是 <a-tabs/> 组件,然后添加事件监听,自动触发reload()
*
* 由于 tabs 组件切换会导致 tinymce 无法输入,
* 只有重新加载才能使用(无论是vue版的还是jQuery版tinymce都有这个通病)
*/
initATabsChangeAutoReload() {
// 获取父级
let tabs = getVmParentByName(this, 'ATabs')
let tabPane = getVmParentByName(this, 'ATabPane')
let modal = getVmParentByName(this,'AModal')
if (tabs && tabPane ) {
// 用户自定义的 key
let currentKey = tabPane.$vnode.key
// 添加事件监听
tabs.$on('change', (key) => {
// 切换到自己时执行reload
if (currentKey === key) {
this.reload()
}
})
}else if(modal){
console.log("tinymce reload!")
this.reload();
}
},
},
watch: {
value(newValue) {
this.myValue = (newValue == null ? '' : newValue)
},
myValue(newValue) {
if (this.triggerChange) {
this.$emit('change', newValue)
} else {
this.$emit('input', newValue)
}
}
}
}
</script>
<style scoped>
</style>
还有几个坑,看这里TinyMCE-vue 组件实现上传word解析后返回到富文本编辑器中