欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用el-upload組件實(shí)現(xiàn)遞歸多文件上傳的全過程

 更新時間:2023年03月31日 09:26:25   作者:至尊丨楷君  
el-upload組件文件上傳都是每個文件請求一次接口,本次實(shí)現(xiàn)一次請求上傳多個文件,下面這篇文章主要給大家介紹了關(guān)于使用el-upload組件實(shí)現(xiàn)遞歸多文件上傳的相關(guān)資料,需要的朋友可以參考下

一、需求描述:

在頁面上點(diǎn)擊按鈕彈出選擇電腦文件的界面,可以一次性選擇多個文件一起上傳到服務(wù)器上,并把上傳成功的文件展示在頁面上。

二、問題闡述:

el-upload是支持多文件上傳的,但是是同步進(jìn)行的,你點(diǎn)擊上傳按鈕,選擇了多個文件后點(diǎn)擊確定,會同時調(diào)用上傳文件的接口,這樣很容易導(dǎo)致服務(wù)器奔潰,導(dǎo)致接口報錯。

三、解決方法:

為了解決這一難題,本文采用遞歸的方法來實(shí)現(xiàn)精準(zhǔn)上傳文件。

四、實(shí)現(xiàn)思路:

遞歸上傳是指:你選擇了n個文件點(diǎn)擊確定后,第一個接口上傳成功或者失敗后,再調(diào)用第二個接口上傳第二個文件,依次等待上傳完所有文件,這樣做法可以大大減輕服務(wù)器的壓力,就是上傳時間會比較長。上傳效果請看下方動態(tài)示例圖

主要邏輯詳解:

1、首先需要先取消組件的自動上傳操作,把屬性auto-upload的值設(shè)置為false,就禁用了文件的自動上傳功能了,把自動轉(zhuǎn)化為手動,之所以選擇多個文件會并行調(diào)用上傳接口,就是這個屬性導(dǎo)致的。

2、屬性auto-upload設(shè)置為false之后,action的屬性就失效了,只會觸發(fā)change事件、上傳失敗on-error事件以及上傳個數(shù)限制before-upload事件。

3、關(guān)鍵點(diǎn)就在于change事件,選擇了多少個文件,這個事件就會執(zhí)行多少次,例如你選擇了100個文件,change事件就會循環(huán)執(zhí)行100次,為了保證上傳的準(zhǔn)確性,這里順手寫了防抖事件,通過防抖,可以清楚的知道,上傳進(jìn)度到哪了,change事件什么時候結(jié)束,在這里就可以開始調(diào)用后端給我們的上傳接口了。

4.因?yàn)槲沂窍霚p少服務(wù)器壓力,既在上一個文件上傳結(jié)束后,再去上傳下一個文件。故,我采用了遞歸一次傳一個(遞歸邏輯在submitUpload2事件里)。同樣的,如果你想只調(diào)用一次接口,將1000個文件傳給后端,那么你就將submitUpload2遞歸事件給修改調(diào),改成調(diào)一次接口,傳所有file文件數(shù)組即可(具體看你們后端的數(shù)據(jù)結(jié)構(gòu))。

5.因?yàn)槭巧蟼鞫鄠€文件,時間肯定長,如果你不想繼續(xù)傳遞后續(xù)文件,就調(diào)用submitAbort即可。但是element文檔說的abort()取消上傳事件不生效。所以我是直接將上傳列表給置空了,所以遞歸也就結(jié)束了就不傳遞了。

6.同樣因?yàn)樯蟼鲿r間長,我就設(shè)置了進(jìn)度條(當(dāng)前已上傳的個數(shù)/所有需要上傳個數(shù))。但是你如果切換到其他頁面的話,再切換到當(dāng)前上傳vue頁面,因?yàn)樯芷谠驅(qū)е驴床坏缴蟼鬟M(jìn)度。所以可以將這個上傳vue頁面使用keep-alive進(jìn)行路由緩存,這樣除了刷新瀏覽器外,切換到當(dāng)前頁還是會讀緩存會看到上傳進(jìn)度。(如果你既想要緩存進(jìn)度條,又想要刷新頁面的list等某些數(shù)據(jù),那么你緩存此頁面,然后在activated單獨(dú)調(diào)獲取list數(shù)據(jù)方法即可)。

7.因?yàn)槲业男枰牵x擇文件成功后,默認(rèn)去上傳,所以我是在防抖事件后就去調(diào)遞歸上傳了。正常情況下,其實(shí)需要點(diǎn)擊這個按鈕然后去上傳的,既手動點(diǎn)擊上傳(被注釋掉了)<!-- <el-button style="margin-left: 10px;" size="small" type="success" @click="submitUpload2">手動點(diǎn)擊上傳</el-button> -->

以下代碼僅供參考,可以直接復(fù)制使用(注意將axios的接口轉(zhuǎn)化為后端提供的接口即可)!

<template>
  <div class="group_insurance_order1" style="padding-top:100px;">
    <!--
      :auto-upload="false" 是否在選取文件后立即進(jìn)行上傳 false阻止自動上傳 -- 且上傳前和上傳成功的事件都不會再觸發(fā) 只會觸發(fā)@change事件了
      :http-request="uploadFile"  覆蓋默認(rèn)的上傳行為,可以自定義上傳的實(shí)現(xiàn)(this.$refs.upload1.submit()  會觸發(fā)調(diào)用uploadFile函數(shù))
    -->
    <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" style="margin-top: -10px;line-height: 20px;">
        將文件拖到此處,<em v-if="!disabledUpload">或點(diǎn)擊上傳(單個文件需小于100M,一次最多上傳1000個pdf文件)</em><em v-else>(文件正在上傳中,請等待...)</em>
      </div>
    </el-upload>
 
    <div>
      <!-- <el-button style="margin-left: 10px;" size="small" type="success" @click="submitUpload2">手動點(diǎn)擊上傳</el-button> -->
      <el-button v-if="showPercent" style="margin-left: 10px;" size="small" type="success" @click="submitAbort">取消后續(xù)文件上傳</el-button>
    </div>
 
    <div style="color:orange;" v-if="showPercent">上傳過程請勿刷新瀏覽器和跳轉(zhuǎn)其他頁面...</div>
    <!-- 進(jìn)度條 -->
    <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,//總上傳個數(shù)
      percentNow: 0,//當(dāng)前上傳個數(shù)
      showDesc: '',//結(jié)束文案
      showPercent: false,//顯示上傳進(jìn)度條
      time: null,// change事件是否結(jié)束 是否可以直接調(diào)手動上傳事件(目前設(shè)置1.5s)
      disabledUpload: false,//正在上傳中 禁止再次選擇文件上傳
 
      fileData: {
      },//上傳參數(shù)
 
      fileList1: [],
 
    }
  },
  activated: {
    // 對于每次進(jìn)入頁面想要刷新的數(shù)據(jù),放在這里調(diào)用即可 例如 this.getList()
  },
  methods: {
    // 超出限制個數(shù)提示
    handleExceed (files, fileList) {
      console.log('當(dāng)前限制一次性最多上傳1000個文件', files, fileList)
      this.$message.warning("當(dāng)前限制一次性最多上傳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("當(dāng)前僅支持pdf格式的文件上傳")
        // return false // 這個return無效 故去掉
      }
 
 
      // 符合條件的進(jìn)入待傳列表
      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('防抖 高頻觸發(fā)后n秒內(nèi)只會執(zhí)行一次  再次觸發(fā)重新計(jì)時')
        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增加數(shù)據(jù)
        this.fileNum.append('name', this.upFileList[0].name)  // append增加數(shù)據(jù)
 
        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 => {
            // 每次上傳當(dāng)前一個后 不論成功失敗就刪除當(dāng)前這個--如果上傳失敗想繼續(xù)傳當(dāng)前這個 就把這兩行注釋掉
            this.percentNow = this.percentNow + 1
            this.upFileList.shift()
 
 
            console.log('上傳返回', res2)
            if (res2.data.success) {
              // this.$message({
              //   message: "上傳成功",
              //   type: 'success'
              // })
 
              // 進(jìn)行遞歸 上傳下一個
              this.submitUpload2()
 
            } else {
              _vm.$message({
                message: res2.data.return_message || '上傳失敗',
                type: "error",
              })
 
              // 進(jìn)行遞歸 上傳下一個
              this.showDesc = '上傳結(jié)束,部分文件上傳失敗'
              this.submitUpload2()
            }
          })
          .catch(error => {
            console.log(error)
            _vm.$message({
              message: error || '上傳失敗',
              type: "error",
            })
 
            // 每次上傳當(dāng)前一個后 不論成功失敗就刪除當(dāng)前這個--如果上傳失敗想繼續(xù)傳當(dāng)前這個 就把這兩行注釋掉
            this.percentNow = this.percentNow + 1
            this.upFileList.shift()
 
            // 進(jìn)行遞歸 上傳下一個
            this.showDesc = '上傳結(jié)束,部分文件上傳失敗'
            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('已部分上傳成功,且取消后續(xù)文件上傳!')
          this.percentTotal = 0
          this.percentNow = 0
 
        }
 
        return false
      }
 
    },
    // 終止后需上傳
    submitAbort () {
      this.showPercent = false
      // .abort()不生效,故自己直接將this.upFileList置空 那么就不會走到遞歸了 就制止后續(xù)的上傳了
      this.upFileList = []
 
 
      // this.upFileList.forEach(ele => {
      //   this.$refs.upload1.abort(ele)
      // })
      // this.$refs.upload1.abort()
      // this.$message.warning('已取消后續(xù)文件上傳!')
    },
    fileErr (err, file, fileList) {
      this.$message({
        message: file.name + '上傳失敗',
        type: "error",
      })
    },
 
 
 
	// 這兩個事件不會再觸發(fā)--因?yàn)樽柚沽俗詣由蟼?
    beforeAvatarUpload (file) {
      console.log('上傳文件前', file)
    },
    msgSuccessOne (data, file, fileList) {
      console.log('成功', file)
    },
 
 
  },
};
</script>

總結(jié)

到此這篇關(guān)于使用el-upload組件實(shí)現(xiàn)遞歸多文件上傳的文章就介紹到這了,更多相關(guān)el-upload遞歸多文件上傳內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論