您好,登錄后才能下訂單哦!
本篇內容介紹了“怎么使用el-upload組件實現遞歸多文件上傳”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
在頁面上點擊按鈕彈出選擇電腦文件的界面,可以一次性選擇多個文件一起上傳到服務器上,并把上傳成功的文件展示在頁面上。
el-upload是支持多文件上傳的,但是是同步進行的,你點擊上傳按鈕,選擇了多個文件后點擊確定,會同時調用上傳文件的接口,這樣很容易導致服務器奔潰,導致接口報錯。
為了解決這一難題,本文采用遞歸的方法來實現精準上傳文件。
遞歸上傳是指:你選擇了n個文件點擊確定后,第一個接口上傳成功或者失敗后,再調用第二個接口上傳第二個文件,依次等待上傳完所有文件,這樣做法可以大大減輕服務器的壓力,就是上傳時間會比較長。上傳效果請看下方動態示例圖
1、首先需要先取消組件的自動上傳操作,把屬性auto-upload的值設置為false,就禁用了文件的自動上傳功能了,把自動轉化為手動,之所以選擇多個文件會并行調用上傳接口,就是這個屬性導致的。
2、屬性auto-upload設置為false之后,action的屬性就失效了,只會觸發change事件、上傳失敗on-error事件以及上傳個數限制before-upload事件。
3、關鍵點就在于change事件,選擇了多少個文件,這個事件就會執行多少次,例如你選擇了100個文件,change事件就會循環執行100次,為了保證上傳的準確性,這里順手寫了防抖事件,通過防抖,可以清楚的知道,上傳進度到哪了,change事件什么時候結束,在這里就可以開始調用后端給我們的上傳接口了。
4.因為我是想減少服務器壓力,既在上一個文件上傳結束后,再去上傳下一個文件。故,我采用了遞歸一次傳一個(遞歸邏輯在submitUpload2事件里)。同樣的,如果你想只調用一次接口,將1000個文件傳給后端,那么你就將submitUpload2遞歸事件給修改調,改成調一次接口,傳所有file文件數組即可(具體看你們后端的數據結構)。
5.因為是上傳多個文件,時間肯定長,如果你不想繼續傳遞后續文件,就調用submitAbort即可。但是element文檔說的abort()取消上傳事件不生效。所以我是直接將上傳列表給置空了,所以遞歸也就結束了就不傳遞了。
6.同樣因為上傳時間長,我就設置了進度條(當前已上傳的個數/所有需要上傳個數)。但是你如果切換到其他頁面的話,再切換到當前上傳vue頁面,因為生命周期原因導致看不到上傳進度。所以可以將這個上傳vue頁面使用keep-alive進行路由緩存,這樣除了刷新瀏覽器外,切換到當前頁還是會讀緩存會看到上傳進度。(如果你既想要緩存進度條,又想要刷新頁面的list等某些數據,那么你緩存此頁面,然后在activated單獨調獲取list數據方法即可)。
7.因為我的需要是,選擇文件成功后,默認去上傳,所以我是在防抖事件后就去調遞歸上傳了。正常情況下,其實需要點擊這個按鈕然后去上傳的,既手動點擊上傳(被注釋掉了)<!-- <el-button style="margin-left: 10px;" size="small" type="success" @click="submitUpload2">手動點擊上傳</el-button> -->
以下代碼僅供參考,可以直接復制使用(注意將axios的接口轉化為后端提供的接口即可)!
<template> <div class="group_insurance_order1" > <!-- :auto-upload="false" 是否在選取文件后立即進行上傳 false阻止自動上傳 -- 且上傳前和上傳成功的事件都不會再觸發 只會觸發@change事件了 :http-request="uploadFile" 覆蓋默認的上傳行為,可以自定義上傳的實現(this.$refs.upload1.submit() 會觸發調用uploadFile函數) --> <el-upload ref="upload1" class="upload-demo" action="/chc-shop/api/v1/accident/szcp/electronicfile/upload" accept=".pdf" :disabled="disabledUpload" :auto-upload="false" :on-change="changeFile" :on-error='fileErr' :on-exceed="handleExceed" :file-list="fileList1" :before-upload="beforeAvatarUpload" :on-success="msgSuccessOne" :data="fileData" list-type="picture" drag :show-file-list="false" :multiple="true" :limit="1000"> <i class="el-icon-upload"></i> <div class="el-upload__text" > 將文件拖到此處,<em v-if="!disabledUpload">或點擊上傳(單個文件需小于100M,一次最多上傳1000個pdf文件)</em><em v-else>(文件正在上傳中,請等待...)</em> </div> </el-upload> <div> <!-- <el-button size="small" type="success" @click="submitUpload2">手動點擊上傳</el-button> --> <el-button v-if="showPercent" size="small" type="success" @click="submitAbort">取消后續文件上傳</el-button> </div> <div v-if="showPercent">上傳過程請勿刷新瀏覽器和跳轉其他頁面...</div> <!-- 進度條 --> <el-progress v-if="showPercent" :percentage="Number((percentNow*100/percentTotal).toFixed(0))"></el-progress> </div> </template> <script> import axios from 'axios' export default { data () { return { fileNum: '', // 單詞遞歸上傳的文件 upFileList: '',//需要依次上傳的待傳列表 percentTotal: 0,//總上傳個數 percentNow: 0,//當前上傳個數 showDesc: '',//結束文案 showPercent: false,//顯示上傳進度條 time: null,// change事件是否結束 是否可以直接調手動上傳事件(目前設置1.5s) disabledUpload: false,//正在上傳中 禁止再次選擇文件上傳 fileData: { },//上傳參數 fileList1: [], } }, activated: { // 對于每次進入頁面想要刷新的數據,放在這里調用即可 例如 this.getList() }, methods: { // 超出限制個數提示 handleExceed (files, fileList) { console.log('當前限制一次性最多上傳1000個文件', files, fileList) this.$message.warning("當前限制一次性最多上傳1000個文件") }, changeFile (file, fileList) { this.disabledUpload = true console.log('changeFile', file, fileList) const isLt2M = file.size / 1024 / 1024 < 100 if (!isLt2M) { this.$message.warning('上傳文件大小不能超過 100M') // return false // 這個return無效 故去掉 } if (!(file.name.indexOf('.pdf') > -1)) { this.$message.warning("當前僅支持pdf格式的文件上傳") // return false // 這個return無效 故去掉 } // 符合條件的進入待傳列表 this.upFileList = [] for (let x of fileList) { if (x.raw && (x.name.indexOf('.pdf') > -1) && (x.size / 1024 / 1024 < 100)) {// 過濾掉非pdf 和小于100M的 this.upFileList.push(x.raw) this.percentTotal = this.upFileList.length this.percentNow = 0 this.showPercent = false this.showDesc = '' } } clearTimeout(this.time) this.time = setTimeout(() => { this.time = null console.log('防抖 高頻觸發后n秒內只會執行一次 再次觸發重新計時') this.fnBegin()//說明此時change了所有文件了 可以上傳了 }, 1500) }, fnBegin () { console.log('此時change了所有文件 開始上傳', this.upFileList) this.submitUpload2() }, // 正式上傳掉后端接口 submitUpload2 () { if (this.upFileList.length > 0) { this.showPercent = true this.fileNum = new FormData() // new formData對象 this.fileNum.append('file', this.upFileList[0]) // append增加數據 this.fileNum.append('name', this.upFileList[0].name) // append增加數據 let _vm = this axios({ url: '/chc-shop/api/v1/accident/szcp/electronicfile/upload', headers: { "Content-Type": "multipart/form-data", }, method: "post", data: this.fileNum, }) .then(res2 => { // 每次上傳當前一個后 不論成功失敗就刪除當前這個--如果上傳失敗想繼續傳當前這個 就把這兩行注釋掉 this.percentNow = this.percentNow + 1 this.upFileList.shift() console.log('上傳返回', res2) if (res2.data.success) { // this.$message({ // message: "上傳成功", // type: 'success' // }) // 進行遞歸 上傳下一個 this.submitUpload2() } else { _vm.$message({ message: res2.data.return_message || '上傳失敗', type: "error", }) // 進行遞歸 上傳下一個 this.showDesc = '上傳結束,部分文件上傳失敗' this.submitUpload2() } }) .catch(error => { console.log(error) _vm.$message({ message: error || '上傳失敗', type: "error", }) // 每次上傳當前一個后 不論成功失敗就刪除當前這個--如果上傳失敗想繼續傳當前這個 就把這兩行注釋掉 this.percentNow = this.percentNow + 1 this.upFileList.shift() // 進行遞歸 上傳下一個 this.showDesc = '上傳結束,部分文件上傳失敗' this.submitUpload2() }) } else { this.disabledUpload = false this.showPercent = false this.upFileList = [] //清空待傳列表 this.$refs.upload1.clearFiles() this.fileList1 = [] if ((this.percentNow == this.percentTotal) && this.percentTotal) { this.$message.success(this.showDesc ? this.showDesc : '已全部上傳成功!') this.percentTotal = 0 this.percentNow = 0 this.showDesc = '' } else if ((this.percentNow == this.percentTotal) && this.percentTotal == 0) { this.$message.warning('請先選擇文件!') this.percentTotal = 0 this.percentNow = 0 } else { this.$message.success('已部分上傳成功,且取消后續文件上傳!') this.percentTotal = 0 this.percentNow = 0 } return false } }, // 終止后需上傳 submitAbort () { this.showPercent = false // .abort()不生效,故自己直接將this.upFileList置空 那么就不會走到遞歸了 就制止后續的上傳了 this.upFileList = [] // this.upFileList.forEach(ele => { // this.$refs.upload1.abort(ele) // }) // this.$refs.upload1.abort() // this.$message.warning('已取消后續文件上傳!') }, fileErr (err, file, fileList) { this.$message({ message: file.name + '上傳失敗', type: "error", }) }, // 這兩個事件不會再觸發--因為阻止了自動上傳 beforeAvatarUpload (file) { console.log('上傳文件前', file) }, msgSuccessOne (data, file, fileList) { console.log('成功', file) }, }, }; </script>
“怎么使用el-upload組件實現遞歸多文件上傳”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。