開發后台系統的時候,富文本編輯器肯定是必不可少的,然后呢~在天朝當然要屬百度編輯器(UEditor)最成熟了,功能全面,文檔齊全(相對),ui優美(。。。,對於程序員來說)等等許多方面(MMP,還不是因為有中文文檔和國人使用經驗參考),所以使用百度編輯器就是不二之選了,早前再angular1的項目中使用過UE,主要是由后端配置好用,直接扔一個demo給我們,照着插入就OK了,現在呢,只能自己封裝個組件咯,網上其實已經有很多關於在vue項目中引入UE的博文了,我也是看着那些博文摸索過來的,也遇到了一些文中沒有提到的坑,所以記錄一下,希望有用;
-
vue項目中引入UE的方式:
首先,當然是去官網把ue的本地下載下來,使用vue-cli構建項目的話通常都是把外部插件放到static文件夾中,所以目錄就會呈現如下:
無視前面幾個文件夾 -
配置Ueditor.config.js
主要的還是
···var URL = window.UEDITOR_HOME_URL || '/static/ueditor/';···
其他的配置大可看看官方文檔設置一下,常用的默認寬高、默認功能按鈕、層級(zIndex,我就遇到過這個坑。。)
- 創建components
在components中創建基礎的vue組件模板,引入ueditor的主要文件,然后就是一些初始話的設置,這里就直接上代碼了,網上也都一樣
<template>
<div>
<!--下面通過傳遞進來的id完成初始化-->
<script :id="randomId" type="text/plain"></script>
</div>
</template>
<script>
//主體文件引入
import '../../../static/ueditor/ueditor.config.js'
import '../../../static/ueditor/ueditor.all.min.js'
import '../../../static/ueditor/lang/zh-cn/zh-cn.js'
export default {
name: 'UE',
props: {
value: {
default: function() {
return ''
}
},
//配置可以傳遞進來
ueditorConfig: {}
},
data() {
return {
//每個編輯器生成不同的id,以防止沖突
randomId: 'editor_' + (Math.random() * 100000000000000000),
//編輯器實例
instance: null,
ready: false,
};
},
watch: {
value: function(val, oldVal) {
if (val != null && this.ready) {
this.instance = UE.getEditor(this.randomId, this.ueditorConfig);
this.instance.setContent(val);
}
}
},
//此時--el掛載到實例上去了,可以初始化對應的編輯器了
mounted() {
this.initEditor();
},
beforeDestroy() {
// 組件銷毀的時候,要銷毀 UEditor 實例
if(this.instance !== null && this.instance.destroy) {
this.instance.destroy();
}
},
methods: {
initEditor() {
const _this = this;
//dom元素已經掛載上去了
this.$nextTick(() => {
this.instance = UE.getEditor(this.randomId, this.ueditorConfig);
// 綁定事件,當 UEditor 初始化完成后,將編輯器實例通過自定義的 ready 事件交出去
this.instance.addListener('ready', () => {
this.ready = true;
this.$emit('ready', this.instance);
});
});
},
setText(con) {
this.instance = UE.getEditor(this.randomId, this.ueditorConfig);
this.instance.setContent(con);
},
}
};
</script>
<style>
</style>
使用方式:
<template>
<div class="box-container">
<Ueditor @ready="editorReady" ref="ue" :value="defaultMSG" :ueditorConfig="config" style="width:100%;"></Ueditor>
</div>
</template>
<script>
import Ueditor from '@/components/Ueditor';
export default {
data() {
return {
defaultMSG: null,
form: {
content: ''
},
config: {
initialFrameHeight: 500
}
};
},
created() {
this.getInfo();
},
components: {
Ueditor
},
methods: {
getInfo() {
getCategoryInfo(this.form.cateId).then(res => {
if (res.message =='SUCCESS') {
this.form = Object.assign({}, res.data);
this.defaultMSG = this.form.content;
} else {
this.$message({
message: res.message,
type: 'error',
duration: 5 * 1000
});
}
})
},
editorReady(instance) {
instance.setContent(this.form.content);
instance.addListener('contentChange', () => {
this.form.content = instance.getContent();
});
},
}
}
</script>
<style scoped lang="scss">
</style>
- 這樣基本上就可以將百度編輯器引入到各個頁面中去了,這是修改后的版本,介紹下遇到的坑
第一個問題:異步請求的數據如何賦值到content中去:
這一步也跟一個之前遇到的坑有關,就是:vue2父組件傳遞props異步數據到子組件的問題,之后在整理下再發個博文吧;
為什么會有這個問題呢? 因為之前傻乎乎的在ueditor組件上綁定的值是 form.content,然后監聽contentChange時賦值給的還是form.content,這樣就導致了內容一直刷新,使得光標會自動跳到最前方,錯誤的示范如下:
//在使用中:
<Ueditor @ready="editorReady" ref="ue" :value="form.content" :ueditorConfig="config" style="width:100%;"></Ueditor>
editorReady(instance) {
instance.setContent(this.form.content);
instance.addListener('contentChange', () => {
this.form.content = instance.getContent();
});
},
//就這樣,在ueditor中已經watch了value,導致form.content一變,就處罰setContent,然后又觸發了contentChange事件,又賦值了一遍。。。。如此就導致內容一直更新,光標一直會移動到最前放。。。所以,最主要的問題還是在父級組件中設置一個defaultMSG來保存默認值,作為第一次內容的填充,填充完之后的修改就不關它啥事了。。。
第二個問題:使用watch添加默認值的時候,在watch觸發時,ueditor卻還沒有ready,會導致報錯,各種奇葩的錯,所以呢,

添加一個ready屬性,在initEditor的時候監聽ready事件,在其中賦值 this.ready = true;就可以避免那些亂七八糟的錯誤了。
第三個問題:在一個沒有默認值的時候,需要清空content的內容時,設置defaultMSG為空是不行的,如下效果,要再切換時清空content

這時候就要用到我們在組件內添加的setText method了,使用的是vue的$refs.組件ref名來獲取組件實例,並可以使用methods中的方法
this.$refs.ue.setText(''); //ue是父級在組件上加的 ref="ue"屬性
第四個問題: 百度編輯器層級問題
我將百度編輯器放置在element-ui的dialog中,dialog組件默認層級是2000,這就導致了UE中一些定位的下拉框層級不夠,被隱藏在了下面,比如表情,字體,字號這些設置,
經過一番查找,發現UE中有個配置項 zIndex用於設置ueditor編輯器層級的基數,瞬間解決~~

哦哦,對了,還有ueditor文件上傳這塊的內容,由於我們用的是阿里雲服務器保存圖片,所以ueditor自帶的上傳圖片功能就不能使用了,要自定義功能,這部分等下篇博文再寫把,沒什么干貨,都是自己踩的坑,希望有用,謝謝。
