問題描述
Tinymce 富文本編輯器作爲子組件引入時,如果富文本編輯器已經綁定過值,再通過 v-model 雙向綁定去更新值時,值不會發生變化
這是我第三次單擊編輯,此時由於富文本中已經有值,再次回寫不生效,因此預覽正確應該爲 a,但是富文本中不正確。
問題分析
代碼位置:/src/components/Tinymce/index.vue
該文件是 Tinymce
富文本子組件,其中監聽器中 value
就是用來更新富文本中的值的
watch: {
value(val) {
if (!this.hasChange && this.hasInit) {
this.$nextTick(() =>
window.tinymce.get(this.tinymceId).setContent(val || ''))
}
},
},
你會發現這個判斷,含義是值不變化時才走下面的賦值,由於沒研究過富文本,因此我通過簡單粗暴的 console.log 對值進行分析,然後去找了這個值變動的地方,得出以下結論
!this.hasChange
- 第一次編輯: 由於富文本組件未初始化,直接通過 v-model 回寫是成功的,此時沒有觸發這個監聽器,但是會通過初始化函數 init_instance_callback 進行回寫。
- 第二次編輯: 富文本組件已初始化,此次編輯
value 監聽器
成功觸發回寫,所以第二次也是成功的。但也會觸發 init_instance_callback 中的 editor.on 函數,此時this.hasChange
會被變成true
,目的是讓你在編輯時候不會觸發value 監聽器
,因此 editor.on 這個函數應該是進入編輯狀態的意思 - 第三次編輯: 由於第二次中
this.hasChange
變成true
,因此!this.hasChange
爲false
,value 監聽器
就不再起作用了,這也是爲什麼,第三次開始回寫就不成功。
init_instance_callback
init_instance_callback: editor => {
if (_this.value) {
editor.setContent(_this.value)
}
_this.hasInit = true
editor.on('NodeChange Change KeyUp SetContent', () => {
this.hasChange = true
this.$emit('input', editor.getContent())
})
},
解決方案
首先一點,我們不能去除 !this.hasChange
的判斷,因爲這個是爲了防止你在編輯時候,觸發回寫導致卡頓與失去焦點,可以自己試下。
因此我的方案就是父組件去調用子組件中的賦值函數從而實現回寫。
子組件函數:
搜下就有了,通過這個函數能實現回寫
setContent(value) {
window.tinymce.get(this.tinymceId).setContent(value)
},
父組件調用:
Tinymce 增加 ref 引用來獲取子組件信息
<tinymce ref="tinymce" v-model="form.text" :height="300" />
然後在編輯時候直接調用子組件的 setContent(value) 函數進行賦值
if (this.$refs['tinymce'] !== undefined) {
this.$refs['tinymce'].setContent(this.form.text)
}