最近用vue+element-ui開發一套後臺管理系統,其中項目中須要用到富文本編輯器,這裏總結下開發過程當中遇到的坑和使用方法。
剛開始用的是vue-quill-editor結合element-ui上傳圖片到服務器,name問題來了 按照官方文檔上面的方式。下面是個人代碼php
<template> <div> <!-- 圖片上傳組件輔助--> <el-upload class="avatar-uploader" :action="serverUrl" name="img" :headers="header" :show-file-list="false" :on-success="uploadSuccess" :on-error="uploadError" :before-upload="beforeUpload"> </el-upload> <!--富文本編輯器組件--> <el-row v-loading="uillUpdateImg"> <quill-editor v-model="detailContent" ref="myQuillEditor" :options="editorOption" @change="onEditorChange($event)" @ready="onEditorReady($event)" > </quill-editor> </el-row> </div>
</template>
<script>前端
export default { data() { return { quillUpdateImg: false, // 根據圖片上傳狀態來肯定是否顯示loading動畫,剛開始是false,不顯示 serverUrl: '', // 這裏寫你要上傳的圖片服務器地址 header: {token: sessionStorage.token}, // 有的圖片服務器要求請求頭須要有token之類的參數,寫在這裏 detailContent: '', // 富文本內容 editorOption: {} // 富文本編輯器配置 } }, methods: { // 上傳圖片前 beforeUpload(res, file) {}, // 上傳圖片成功 uploadSuccess(res, file) {}, // 上傳圖片失敗 uploadError(res, file) {} } }
</script>vue
那麼咱們須要怎樣將富文本圖片上傳這個按鈕跟自定義的文件上傳作綁定呢。
很簡單,咱們須要在editorOption配置中這麼寫 export default {
data() {element-ui
return { quillUpdateImg: false, // 根據圖片上傳狀態來肯定是否顯示loading動畫,剛開始是false,不顯示 serverUrl: '', // 這裏寫你要上傳的圖片服務器地址 header: {token: sessionStorage.token}, // 有的圖片服務器要求請求頭須要有token之類的參數,寫在這裏 detailContent: '', // 富文本內容 editorOption: { placeholder: '', theme: 'snow', // or 'bubble' modules: { toolbar: { container: toolbarOptions, // 工具欄 handlers: { 'image': function (value) { if (value) { document.querySelector('#quill-upload input').click() } else { this.quill.format('image', false); } } } } } } } }
}後端
可是這裏問題就出現了,當你用element-ui upload方法上傳時你會發現上傳不成功,emmmm~你會發現上傳時Request Method 方式爲OPTIONS,這跟平時的提交方式不同,Status Code等於204,,去網上又查閱了下,發現這種請求方式,可是最終仍是沒有解決掉,好像是須要後端也要相應的改下東西
因此走到這裏只能用另一種方式去實現相同的功能了————Ueditor服務器
第一步:先按照官方的提示 去官網下載相應的代碼,我這裏後端語言是PHP因此我下的是PHP的版本,根據需求去下載
第二步:ueditor裏除了php文件都放到static文件,這是個人目錄結構
第三步:將PHP文件放到後端去,我這邊項目是我直接放到ftp上面去的,結構以下
第四步:我這邊封裝成了一個公共組件,由於有不少頁面須要用到 <template>
<div>session
<script id="editor" type="text/plain"></script>
</div>
</template>app
<script>
//import AppConfig from '@/config'
import '../../../static/ueditor/ueditor.config.js'
import '../../../static/ueditor/ueditor.all.js'
import '../../../static/ueditor/lang/zh-cn/zh-cn.js'編輯器
export default {函數
name: "UEditor", props: { id: { type: String }, config: { type: Object }, defaultMsg: { type: String }, }, created() { //this.$emit('defaultMsgVlaue', this.names) }, data() { return { editor: null, names: '' } }, mounted() { //初始化UE const _this = this; this.initEditor() //this.editor = UE.getEditor(this.id, this.config); // this.editor.addListener('ready', () => { // this.editor.setContent(_this.defaultMsg); // }); }, destoryed() { this.editor.destory(); }, methods: { getUEContent: function() { return this.editor.getContent(); }, initEditor() { let _this= this; this.editor = UE.getEditor('editor', this.config) //編輯器準備就緒後會觸發該事件 this.editor.addListener('ready',()=>{ //設置能夠編輯 this.editor.setEnabled(); this.editor.setContent(_this.defaultMsg); }) //編輯器內容修改時 this.selectionchange() }, //編輯器內容修改時 selectionchange() { this.editor.addListener('selectionchange', () => { //this.content = this.ue.getContent() }) } }, activated() { //初始化編輯器 this.initEditor() }
}
</script>
頁面調用以下
<template>
<div id="app" class="hello">
<el-button size="primary" type="info" icon="plus" @click="openWindow">打開窗口</el-button> <el-dialog title="新增菜單" size="small" v-model="addFormVisible" :close-on-click-modal="false"> <div> <el-button size="primary" type="info" icon="plus" @click="getContent">獲取內容</el-button> <UEditor :config=config ref="ueditor" :defaultMsg=defaultMsg></UEditor> </div> </el-dialog>
</div>
</template>
<script>
import {UEditor} from './ueditor/index.js'
export default{
name: 'hello', components: {UEditor}, data(){ return { config: { /*//能夠在此處定義工具欄的內容 toolbars: [ ['fullscreen', 'source','|', 'undo', 'redo','|','bold', 'italic', 'underline', 'fontborder', 'strikethrough', '|','superscript','subscript','|', 'forecolor', 'backcolor','|', 'removeformat','|', 'insertorderedlist', 'insertunorderedlist', '|','selectall', 'cleardoc','fontfamily','fontsize','justifyleft','justifyright','justifycenter','justifyjustify','|', 'link','unlink'] ],*/ autoHeightEnabled: false, autoFloatEnabled: true, //是否工具欄可浮動 initialContent:'請輸入內容', //初始化編輯器的內容,也能夠經過textarea/script給值,看官網例子 autoClearinitialContent:true, //是否自動清除編輯器初始內容,注意:若是focus屬性設置爲true,這個也爲真,那麼編輯器一上來就會觸發致使初始化的內容看不到了 initialFrameWidth: null, initialFrameHeight: 450, BaseUrl: '', UEDITOR_HOME_URL: 'static/ueditor/' }, addFormVisible: false } }, methods: { openWindow: function(){ this.addFormVisible = true; }, //獲取文檔內容 getContent: function(){ let content = this.$refs.ueditor.getUEContent(); console.log(content); alert(content); } }
}
</script>
注意:在這裏封裝成一個公共組件了,可是在使用的過程當中會發現,在同一頁面回顯數據到ueditor時只會渲染一次,這可怎麼辦呢, 這裏想到了用watch來監聽,而後再將數據放到ueditor裏,這裏我用的參數名是defaultMsg,代碼以下: watch: { 'defaultMsg': { handler(newValue, oldValue) { //父組件param對象改變會觸發此函數 this.editor.setContent(newValue); }, deep: true } } 這樣的話再同一個頁面回顯ueditor時就會實時改變,作到這裏我想着試下在其餘頁面是否能夠,由於有多個路由頁面須要用到ueditor,當我在其餘頁面打開ueditor時,發現ueditor加載不出來了,而後我就納悶了,而後排查了不少問題以後,終於知道是由於每次只初始化了ueditor,可是在關閉頁面時沒有將其銷燬,因此須要在上面封裝的公共組件裏去銷燬下 destroyed() { //銷燬編輯器實例,使用textarea代替 this.editor.destroy() //重置編輯器,可用來作多個tab使用同一個編輯器實例 //若是要使用同一個實例,請註釋destroy()方法 // this.ue.reset() } 這樣的話就解決了在多個路由頁面的時候ueditor不現實的問題。 第五步:配置文件上傳和回顯,咱們須要在上傳圖片,而且讓上傳的圖片回顯到ueditor裏,首先先將文件ueditor/ueditor.config.js裏的serverUrl換成本身項目的服務器路徑
這裏配置以後就能夠直接使用了
遇到的其餘問題以下:前端代碼必須跟PHP文件放在同一個域名上,我以前是將兩塊代碼分別放到不一樣FTP上,這樣致使ueditor裏文件能夠上傳可是提示上傳失敗,這樣上傳的圖片無法回顯 有些仍是不清楚的,或者有其餘更好實現效果的方法的夥伴能夠跟我留言,歡迎共同進步