Element上傳組件隊(duì)列上傳實(shí)現(xiàn)

問(wèn)題:項(xiàng)目基于vue開(kāi)發(fā),使用element上傳組件,該組件在文件選取后會(huì)會(huì)默認(rèn)開(kāi)始上傳,但是這樣存在一個(gè)問(wèn)題:上傳任務(wù)太多可能導(dǎo)致部分素材上傳不成功出現(xiàn)卡死的情況;服務(wù)器帶寬不夠,同時(shí)上傳速度慢,影響效率。

需求:使用隊(duì)列上傳,按需設(shè)置一次允許上傳多少文件,上傳完成一個(gè)自動(dòng)新增到隊(duì)列中,直到全部上傳完成。

隊(duì)列思想圖:

1599639274821.png

主要代碼:

html部分


<el-upload

  ref="upload"

  :data="data"

  accept="image/jpeg,image/gif,image/png,image/jpg,image/svg"

  action="#"

  list-type="picture-card"

  multiple

  :limit="20"

  :file-list="materialList"

  :http-request="customUpload"

  :before-upload="beforeUpload"

  :on-exceed="exceedFiles"

  :on-success="handleSuccess">

</el-upload>

js部分


data() {

      return {

        uploadList:[],  //上傳隊(duì)列數(shù)組

        onQueue: false,  //是否在上傳

        uploadItems: [], //正在上傳的數(shù)組

        uploadLen: 5,  //上傳文件個(gè)數(shù)限制

        uploadLine: 0,  //上傳文件線程

      };

    },

watch: {

//監(jiān)聽(tīng)上傳隊(duì)列數(shù)組是否有上傳完的,如有則觸發(fā)以下代碼

      uploadList (Newfile) {

      //當(dāng)onQueue為true也就是在上傳中或者uploadList文件數(shù)組上傳完為空時(shí),不繼續(xù)往下執(zhí)行

        if (this.onQueue === true || Newfile.length == 0 ) return

        let files = [ ...Newfile ]

        //判斷上傳文件線程是否小于設(shè)置的上傳文件個(gè)數(shù)限制

        if (this.uploadLine < this.uploadLen) {

          let newQueueLine = this.uploadLen - this.uploadLine

          //截取剩余文件放入上傳數(shù)組

          let index = this.uploadLine > 0? this.uploadLen - 1 : 0

          this.uploadItems = files.splice(index, newQueueLine)

          this.uploadLimit(this.uploadItems)

        }

      },

},

methods:{

//上傳限制

      uploadLimit(items) {

      //遍歷文件長(zhǎng)度,就循環(huán)幾次上傳隊(duì)列函數(shù)

        for (let item of items) {

          this.queueUpload(item)

        }

      },

  //上傳之前進(jìn)行判斷,如uploadList的中有該文件,則不讓添加進(jìn)去

      beforeUpload(file) {

        //隊(duì)列去重

        if (this.uploadList.length == 0){

          return true

        }

        for (let item of this.uploadList) {

          if (item.file.name == file.name){

            return  false

          }

        }

        return true

      },

    //將文件push進(jìn)uploadList中,此時(shí)uploadList變化,觸發(fā)watch中的監(jiān)聽(tīng)方法,開(kāi)始第一次隊(duì)列上傳

      customUpload(file) {

        this.uploadList.push(file)

        return false

      },

      //隊(duì)列上傳

      queueUpload(file) {

        this.onQueue = true

        //開(kāi)始上傳該文件后,對(duì)應(yīng)的上傳文件線程+1

        this.uploadLine++

        let formData =  new FormData()

        formData.append('file', file.file)

        formData.append('token', this.data.token)

        axios({

          url: this.url,

          method: 'post',

          data: formData,

          onUploadProgress: (progressEvent) => {

            let num = progressEvent.loaded / progressEvent.total * 100 | 0

            if (num >= 96.9){

              num = 96.9

            }

            file.onProgress({percent: num})

          }

        }).then(res => {

          file.onProgress({percent: 100})

          file.onSuccess(res.data)

        }).catch(erro => {

          console.log(erro)

        })

      },

      handleSuccess(response, file, fileList) {

      //此處為自定義進(jìn)度條的判斷,不做過(guò)多說(shuō)明

        if (file.percentage >= 96.9) {

          file.percentage = 96.9

        }

        let res = response.data

        file.path = res.path

        file.width = res.width

        file.height = res.height

        file.origin_name = file.name

        let data = { ...this.ruleForm }

        data.paths = [{ origin_name: file.name,img: res.path, height: res.height, width: res.width }]

        add(data).then(response => {

          file.id = response.data.id

          this.materialList = fileList

          this.loading = false

          this.ruleForm.paths = []

          this.$message({

            message: response.msg,

            type: 'success',

            duration: 2000

          });

          file.percentage = 100

          this.spliceUpload(file)

        }).catch(res=> {

          this.spliceUpload(file)

          this.$message({

            message: '上傳失敗請(qǐng)重新上傳',

            type: 'success',

            duration: 2000

          });

        })

      },

    //上傳成功后的操作,無(wú)論此文件添加成功或失敗,uploaList都進(jìn)行刪除此文件

      spliceUpload(file) {

        this.onQueue = false

        let index = this.uploadList.findIndex(item=> {

          return item.file.name == file.name

        })

        this.uploadList.splice(index, 1)

        this.uploadItems.splice(index, 1)

        //刪除該文件后,對(duì)應(yīng)的上傳文件線程-1

        this.uploadLine--

      },

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容