前排提示:現在可以直接使用封裝好的插件vue-quill-editor-upload
需求概述
vue-quill-editor是我們再使用vue框架的時候常用的一個富文本編輯器,在進行富文本編輯的時候,我們往往要插入一些圖片,vue-quill-editor默認的處理方式是直接將圖片轉成base64編碼,這樣的結果是整個富文本的html片段十分冗余,通常來講,每個服務器端接收的post的數據大小都是有限制的,這樣的話有可能導致提交失敗,或者是用戶體驗很差,數據要傳遞很久才全部傳送到服務器。
因此,在富文本編輯的過程中,對於圖片的處理,我們更合理的做法是將圖片上傳到服務器,再將圖片鏈接插入到富文本中,以達到最優的體驗。
廢話不多說,接下來直接看如何改造
改造分析
查閱網上的資料,我感覺提供的方案都不是特別友好,網上搜索的基本都是這一個方法
配合 element-ui 實現上傳圖片/視頻到七牛或者是直接重新寫一個按鈕來進行自定義圖片操作
坦白講,上面這2個方法都很特別,也的確有效果,但是我個人還是覺得不完美,第一個方法寫得太麻煩,第二個方法有點投機取巧。
結合上面兩種方法以及官方的文檔,我這里提供一個新的改造思路給大家參考。
引入element-ui
和第一種方法類似,為了更好的控制上傳的圖片,我這里也是引用了element-ui的上傳圖片組件
``` <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> </div> </template> <script> export default { data() { return { serverUrl: '', // 這里寫你要上傳的圖片服務器地址 header: {token: sessionStorage.token} // 有的圖片服務器要求請求頭需要有token } }, methods: { // 上傳圖片前 beforeUpload(res, file) {}, // 上傳圖片成功 uploadSuccess(res, file) {}, // 上傳圖片失敗 uploadError(res, file) {} } } </script> ```這里要使用element-ui主要有2個好處
- 可以對圖片上傳前,圖片上傳成功,圖片上傳失敗等情況進行操作,也就是代碼中的
:on-success="uploadSuccess" // 圖片上傳成功
:on-error="uploadError" // 圖片上傳失敗
:before-upload="beforeUpload" // 圖片上傳前
- 使用element-ui的v-loading顯示loading動畫
引入vue-quill-editor
這里對於如何安裝和引入vue-quill-editor和就不多做陳述了,不清楚的同學自己Google下哈。
在代碼中寫入vue-quill-editor后如下
<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>
這里可以看到我們用一個<el-row>包裹我們的富文本組件,是為了使用loading動畫,就是v-loading這個設置
重寫點擊圖片按鈕事件
從下圖可以看到,默認的配置中,整個工具欄具備了所有的功能,自然也包括紅圈中的圖片上傳功能了。
那么接下來我們要怎么去重寫這個按鈕的事件呢。
很簡單,我們需要在editorOption配置中這么寫
export default {
data() {
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);
}
}
}
}
}
}
}
}
}
配置中的handlers是用來定義自定義程序的,然而我們配置完后會懵逼地發現,整個富文本編輯器的工具欄的圖片上傳等按鈕都不見了 只保留了幾個基本的富文本功能。
這個是因為添加自定義處理程序將覆蓋默認的工具欄和主題行為
因此我們要再自行配置下我們需要的工具欄,所有功能的配置如下,大家可以按需配置
<script>
// 工具欄配置
const toolbarOptions = [
['bold', 'italic', 'underline', 'strike'], // toggled buttons
['blockquote', 'code-block'],
[{'header': 1}, {'header': 2}], // custom button values
[{'list': 'ordered'}, {'list': 'bullet'}],
[{'script': 'sub'}, {'script': 'super'}], // superscript/subscript
[{'indent': '-1'}, {'indent': '+1'}], // outdent/indent
[{'direction': 'rtl'}], // text direction
[{'size': ['small', false, 'large', 'huge']}], // custom dropdown
[{'header': [1, 2, 3, 4, 5, 6, false]}],
[{'color': []}, {'background': []}], // dropdown with defaults from theme
[{'font': []}],
[{'align': []}],
['link', 'image', 'video'],
['clean'] // remove formatting button
]
export default {
data() {
return {
editorOption: {
placeholder: '',
theme: 'snow', // or 'bubble'
modules: {
toolbar: {
container: toolbarOptions, // 工具欄
handlers: {
'image': function (value) {
if (value) {
alert(1)
} else {
this.quill.format('image', false);
}
}
}
}
}
}
}
}
}
</script>
由於這里的工具欄配置列舉了所有,看起來很長一堆,我建議大家可以寫在單獨一個文件,然后再引入,美觀一點
自定義按鈕事件打開上傳圖片
經過上面的配置,大家點擊一下圖片,可以看出彈出了個1,說明我們的自定義事件生效了,那么接下來,大家的思路是不是就很清晰啦?
我們需要在handlers里面繼續完善我們的圖片點擊事件。
- 第一步,點擊按鈕選擇本地圖片
handlers: {
'image': function (value) {
if (value) {
// 觸發input框選擇圖片文件
document.querySelector('.avatar-uploader input').click()
} else {
this.quill.format('image', false);
}
}
}
在這里我們的自定義事件就結束了,接下來圖片上傳成功或者失敗都由
:on-success="uploadSuccess" // 圖片上傳成功
:on-error="uploadError" // 圖片上傳失敗
:before-upload="beforeUpload" // 圖片上傳前
這三個函數來處理
// 富文本圖片上傳前
beforeUpload() {
// 顯示loading動畫
this.quillUpdateImg = true
},
uploadSuccess(res, file) {
// res為圖片服務器返回的數據
// 獲取富文本組件實例
let quill = this.$refs.myQuillEditor.quill
// 如果上傳成功
if (res.code === '200' && res.info !== null) {
// 獲取光標所在位置
let length = quill.getSelection().index;
// 插入圖片 res.info為服務器返回的圖片地址
quill.insertEmbed(length, 'image', res.info)
// 調整光標到最后
quill.setSelection(length + 1)
} else {
this.$message.error('圖片插入失敗')
}
// loading動畫消失
this.quillUpdateImg = false
},
// 富文本圖片上傳失敗
uploadError() {
// loading動畫消失
this.quillUpdateImg = false
this.$message.error('圖片插入失敗')
}
好了,本文就講到這,目前運行良好,整個文章的代碼比較多,但是實際上需要去深入理解的地方很少,我們只是簡單重定義了圖片按鈕的觸發事件。
對了,大家別忘記安裝element-ui和vue-quill-editor哦。
如果有錯誤,歡迎大家多提提意見,希望這篇文章能幫到有需要的人。