upload带进度条,删除时取消请求封装

el-upload组件封装

  • 重点在于使用http-request后,自带的进度条就被隐藏了,想要使用进度条,想要使用进度就得在axios请求调用onUploadProgress事件,调用onProgess事件,具体axios封装,看自己
this.$api({
        url: '/planApi/drill/script/video/upload',
        method: 'post',
        data: files,
        onUploadProgress: function (progressEvent) { // 处理上传进度事件,在这里改变percentage的值吧
          let percent = (progressEvent.loaded / progressEvent.total * 100).toFixed(0);   //计算出上传的进度,去整数位
          file.onProgress({percent: percent})
        }
      })
  • 第二个重点就是,如果在文件上传中途,删掉文件,如果中止掉当前请求,在http-request请求中
updateFile(file){
	 const CancelToken = axios.CancelToken
     const source = CancelToken.source()
     //在axios封装中
     this.$api({
      cancelToken:source.token,
	}).then(() => {
		//成功后改变文件状态
		file.onSuccess()
 		--------- //自己另外处理自己上传逻辑
	}).catch(() => {
		//关键代码
		const uid = file.file.uid
        const idx = this.$refs.upload.uploadFiles.findIndex(item => item.uid === uid) // 关键作用代码,去除文件列表失败文件(uploadFiles为el-upload中的ref值)
        if (idx > 0) {
          this.$refs.upload.uploadFiles.splice(idx, 1) // 关键作用代码,去除文件列表失败文件
        }
	})
	 // 存储一份uid,知道在删除的时候是杀死的哪个请求
      this.source.push({
        source: source,
        uid: file.file.uid
      })
}
//在调用removeFile方法时
 removeFile(file, i) {
 		//在移除时,还可以判断文件的状态,来进行操作
      if(file.status === 'uploading'){
        this.source.forEach(item => {
          if (item.uid === file.uid) {
            item.source.cancel('您已取消了请求') // 这里的提示会在axios的catch的error中捕获到
          }
        })
      }
      ----- //后续随意自己处理
}
  • 贴上完整代码,而且还可以通过axios中的source来进行,在关闭页面时,取消全部请求的操作,或者在文件没有上传完成时的保存状态提示判断,这些都没有细去研究,这些都可以作为拓展功能
<template>
  <div class="upload">
    <el-upload
      action="#"
      ref="upload"
      :http-request="updateFile"
      :file-list="fileList"
      :before-upload="beforeAvatarUpload"
      :on-remove="removeFile"
    >
      <el-button size="small" type="primary">上传视频</el-button>
      <div v-if="!warnDisabled" slot="tip" class="el-upload__tip" style="color: #fff">
        1.支持flv, mp4, rmvb, swf,ogg,avi类型文件<br/>
        2.上传文件不能超过1GB<br/>
        3.等待出现√才是上传完成
      </div>
    </el-upload>
  </div>
</template>

<script>
import axios from "axios";
export default {
  name: 'tc-upload-video',
  props: {
    previewFileList: {
      type: Array,
      default: () => {
        return []
      }
    },
    warnDisabled: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      fileList: [],
      uploadFileList: [],
      delFileList: [],
      // 存储当前要取消的请求
      source: [],
      // 存储请求的数组
      requestArr: [],
      //  上传成功标志
      isSuccess: true,
      // 是否在中断取消时候出现message提示框
      isShowCancel: false,
    }
  },
  watch: {
    previewFileList: {
      handler: function (val) {
        if (val.length) {
          this.uploadFileList = JSON.parse(JSON.stringify(val))
          this.fileList = val.map(item => {
            return {
              name: item.split('_')[1],
              url: item,
            }
          })
          this.delFileList = []
        }else{
          this.uploadFileList = []
          this.fileList = []
          this.delFileList = []
        }
      },
      immediate: true
    }
  },
  methods: {
    async updateFile(file) {
      let files = new FormData()
      for (let a in file) {
        files.append(a === 'raw' ? 'file' : a, file[a])
      }
      file.isUpload = true
      const CancelToken = axios.CancelToken
      const source = CancelToken.source()
      this.$api({
        url: '/planApi/drill/script/video/upload',
        method: 'post',
        data: files,
        cancelToken:source.token,
        onUploadProgress: function (progressEvent) { // 处理上传进度事件,在这里改变percentage的值吧
          let percent = (progressEvent.loaded / progressEvent.total * 100).toFixed(0);   //计算出上传的进度,去整数位
          file.onProgress({percent: percent})
        }
      }).then(res => {
        file.onSuccess()
        this.uploadFileList.push(res)
        this.$emit('uploadList', this.uploadFileList)
      }).catch(() => {
        const uid = file.file.uid
        const idx = this.$refs.upload.uploadFiles.findIndex(item => item.uid === uid) // 关键作用代码,去除文件列表失败文件(uploadFiles为el-upload中的ref值)
        if (idx > 0) {
          this.$refs.upload.uploadFiles.splice(idx, 1) // 关键作用代码,去除文件列表失败文件
        }
      })
      // 存储一份uid,知道在删除的时候是杀死的哪个请求
      this.source.push({
        source: source,
        uid: file.file.uid
      })
      // 这个直接存储,为了关闭页面刷新页面全部杀死请求
      this.requestArr.push(source)
    },
    beforeAvatarUpload(file) {
      const isLt50M = file.size / 1024 / 1024 < 1000;
      if (!isLt50M) {
        this.$message.warning("上传文件大小不能超过 1GB!");
        return false;
      }
      const validFileType = this.validateVideoType(file.name)
      if (!validFileType) {
        this.$message.error('文件格式错误!')
      }
      return validFileType
    },
    validateVideoType(fileName) {
      fileName = fileName.toLowerCase()
      let fileLimitType = ['flv', 'mp4', 'rmvb', 'swf', 'ogg', 'avi']
      for (let i = 0, len = fileLimitType.length; i < len; i++) {
        if (fileName.endsWith(fileLimitType[i])) {
          return true
        }
      }
      return false
    },
    removeFile(file, i) {
      if(file.status === 'uploading'){
        this.source.forEach(item => {
          if (item.uid === file.uid) {
            item.source.cancel('您已取消了请求') // 这里的提示会在axios的catch的error中捕获到
          }
        })
      }

      let fileObj = {}
      this.uploadFileList.map((item, index) => {
        if (item.split('_').includes(file.name)) {
          fileObj = {
            filename: item,
            index: index
          }
        }
      })
      if (fileObj.filename) {
        this.uploadFileList.splice(fileObj.index, 1)
        this.$emit('uploadList', this.uploadFileList)
        this.delFileList.push(fileObj)
      }
    },
    //在保存的时候调用删除方法
    handleDelFileList() {
      this.delFileList?.length && this.delFileList.map(fileObj => {
        this.$api.delete(`/planApi/drill/script/video/delete?filename=${fileObj.filename}`)
      })
    },
  }
}
</script>

<style scoped lang="scss">
.upload {
  margin: 25px 0;
  max-width: 500px;

  .el-upload__tip {
    color: #fff
  }

  & ::v-deep .el-upload-list__item:hover {
    background: transparent;
  }
}

.warnUpload {
  margin-top: -64px;

  & ::v-deep ul {
    padding-left: 0;
  }
}
</style>


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值