改造vue-quill-editor: 結合element-ui上傳圖片到服務器


前排提示:現在可以直接使用封裝好的插件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"  // 圖片上傳前

引入vue-quill-editor

這里對於如何安裝和引入vue-quill-editor和就不多做陳述了,不清楚的同學自己Google下哈。
在代碼中寫入vue-quill-editor后如下


&lt;template&gt;
    &lt;div&gt;
        &lt;!-- 圖片上傳組件輔助--&gt;
        &lt;el-upload
                class="avatar-uploader"
                :action="serverUrl"
                name="img"
                :headers="header"
                :show-file-list="false"
                :on-success="uploadSuccess"
                :on-error="uploadError"
                :before-upload="beforeUpload"&gt;
        &lt;/el-upload&gt;
        &lt;!--富文本編輯器組件--&gt;
       &lt;el-row v-loading="uillUpdateImg"&gt;
        &lt;quill-editor
                v-model="detailContent"
                ref="myQuillEditor"
                :options="editorOption"
                @change="onEditorChange($event)"
                @ready="onEditorReady($event)"
        &gt;
        &lt;/quill-editor&gt;
       &lt;/el-row&gt;
    &lt;/div&gt;
&lt;/template&gt;
&lt;script&gt;
    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) {}
        }
    }
&lt;/script&gt;

這里可以看到我們用一個<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是用來定義自定義程序的,然而我們配置完后會懵逼地發現,整個富文本編輯器的工具欄的圖片上傳等按鈕都不見了 只保留了幾個基本的富文本功能。

這個是因為添加自定義處理程序將覆蓋默認的工具欄和主題行為
因此我們要再自行配置下我們需要的工具欄,所有功能的配置如下,大家可以按需配置


&lt;script&gt;
// 工具欄配置
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);
                  }
                }
              }
            }
          }
        }
    }
 }
}

&lt;/script&gt;

由於這里的工具欄配置列舉了所有,看起來很長一堆,我建議大家可以寫在單獨一個文件,然后再引入,美觀一點

自定義按鈕事件打開上傳圖片

經過上面的配置,大家點擊一下圖片,可以看出彈出了個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' &amp;&amp; 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哦。
如果有錯誤,歡迎大家多提提意見,希望這篇文章能幫到有需要的人。

原文地址:https://segmentfault.com/a/1190000012620431


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM