開發後臺系統的時候,富文本編輯器確定是必不可少的,而後呢~在天朝固然要屬百度編輯器(UEditor)最成熟了,功能全面,文檔齊全(相對),ui優美(。。。,對於程序員來講)等等許多方面(MMP,還不是由於有中文文檔和國人使用經驗參考),因此使用百度編輯器就是不二之選了,早前再angular1的項目中使用過UE,主要是由後端配置好用,直接扔一個demo給咱們,照着插入就OK了,如今呢,只能本身封裝個組件咯,網上其實已經有不少關於在vue項目中引入UE的博文了,我也是看着那些博文摸索過來的,也遇到了一些文中沒有提到的坑,因此記錄一下,但願有用;css
vue項目中引入UE的方式:
首先,固然是去官網把ue的本地下載下來,使用vue-cli構建項目的話一般都是把外部插件放到static文件夾中,因此目錄就會呈現以下:
無視前面幾個文件夾vue
配置Ueditor.config.js
主要的仍是程序員
···var URL = window.UEDITOR_HOME_URL || '/static/ueditor/';···vue-cli
其餘的配置大可看看官方文檔設置一下,經常使用的默認寬高、默認功能按鈕、層級(zIndex,我就遇到過這個坑。。)element-ui
<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;就能夠避免那些亂七八糟的錯誤了。dom
第三個問題:在一個沒有默認值的時候,須要清空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自帶的上傳圖片功能就不能使用了,要自定義功能,這部分等下篇博文再寫把,沒什麼乾貨,都是本身踩的坑,但願有用,謝謝。