el-upload 自定义上传+真实进度条

本文介绍了如何在项目中上传大文件到OSS服务,重点讨论了使用异步方法处理上传过程中的进度显示问题,包括纯前端和前后端结合两种方法,并提到了常见错误“reqs[uid].abortisnotafunction”的解决方案。
摘要由CSDN通过智能技术生成

项目是上传oss接口的 但是视频高达小100M,所以需要用真实的进度条
(项目是只上传一个文件 多个文件需要自行修改)

特别注意:当文件上传删除时 浏览器报错 “reqs[uid].abort is not a function"
原因一:api 中 http-request这个方法 是一个异步方法,不能使用 async 不然会报错误
原因一:如果还是有这个错误请看下面代码 有解决方法!!!!

效果图:
在这里插入图片描述

方法一:纯前端实现
优点:不需要后端单独写接口
缺点:只能获取文件的上传速度 并不能保证结束后 接口一定返回地址

方法二:前端+后端实现
优点:进度条是真实的,但是太小文件上传时进度条的效果有些不太完美
缺点:需要后端单独写获取文件上传oss的接口

<template>
  <el-upload
      :limit="1"
      :on-preview="handlePictureCardPreview"
      class="el-uploadfeng"
      ref="files"
      action="#"
      :file-list="fileList"
      :before-upload="beforeAvatarUpload"
      :on-change="changeData"
      accept=".mp3,.mp4,.gif,.png,.jpg,.mpeg,.mpg"
      :http-request="handleRequest"
      :before-remove="handleBeforeRemove"
      :on-remove="handleRemove"
    >
     
      <i  class="el-icon-plus" v-if="fileList.length == 0 && !isUpload" ></i>
    </el-upload>
    <div class="newpro">
      <el-progress
        v-if="isUpload"
        :stroke-width="10"
        :percentage="progressPercent"
        style="width: 100%"
      ></el-progress>
    </div>

</template>
<script>
import axios from "axios";


export default {
  data() {
    return {
      uploadTimer: null,//调取进度条的轮询定时器
      isUpload: false,//文件是否上传中
      progressPercent: 0,//进度条当前进度
      curPercentage: 0,
      fileList: [],//上传文件
      currentFile: {},//当去上传的文件
    };
  },
  watch: {
  //监听文件是否上传
    isUpload: {
      handler(val, oldVal) {
        if (this.isUpload) {
          this.uploadTimer = setInterval(async () => {
            //需要定时执行的代码
            this.progressPercent = await this.getProgress(this.currentFile);
          }, 1000);
        } else {
          clearInterval(this.uploadTimer);
          this.currentFile = {};
        }
      },
      deep: true,
    },
  },

 
  methods: {
    beforeAvatarUpload(file, fileList) {
      console.log(file, 99999999999999);
    
    },
    

    async getProgress(file) {
      var that = this;
      console.log("🚀 ~ handleRequest ~ data222:", file.uid);
      var progress = 0;
   
      await axios
        .get('获取进度条接口地址')
        .then(async (res) => {
         //percent是后端返回的进度
          progress = Number(res.data.percent);
          if (progress == 100) {
            this.isUpload = false;
            clearInterval(this.uploadTimer);
            that.uploadTimer = null;
            await that.handlePicSuccess(res.data, file);
            this.currentFile = {};
            this.$forceUpdate();
          }
        });
    
      return progress;
    },
     handleRequest(option) {
      var that = this;
      const { onProgress, onSuccess, onError } = option;
      this.progressPercent = 0;

      this.currentFile = option.file;
      let formdata = new FormData();
      formdata.append("file", option.file);
      formdata.append("fileName", option.file.fileNamee);
      formdata.append("uid", option.file.uid);
      console.log("🚀 ~ handleRequest ~ formdata:", formdata);
      this.isUpload = true;
        // 这是方法一的开始
      // const config = {
      //   onUploadProgress: (progressEvent) => {
      //     // progressEvent.loaded:已上传文件大小
      //     // progressEvent.total:被上传文件的总大小
      //     this.progressPercent = Number(
      //       ((progressEvent.loaded / progressEvent.total) * 100).toFixed(2)
      //     );
      //   },
      // };
       // 这是方法一的结束
       axios
        .post('文件上传oss接口地址 ', 
        formdata,
        //config,这是方法一的配置
        )
        .then((res) => {
          console.log("🚀 ~ this.$axios.post ~ res111:", res);
          if (res.data.code == 0) {
            that.fileList[that.fileList.length - 1].status = "done";
           
            onSuccess();
          } else {
            that.fileList[that.fileList.length - 1].ststus = "error";
            onError();
          }
         
        }); 
        //如果浏览器出现 reqs[uid].abort is not a function 加上即可 
        // var prom = new Promise((resolve, reject) => {});
        //   prom.abort = () => {};
        //   return prom;
    },

   
   
   
 //文件上传成功
    handlePicSuccess(res, file) {
      console.log(res, file, "999999999");
      if (res.msg == "success") {
        this.addForm.url = res.url;
        this.fileList.push({
          name: file.name,
          url: res.url,
        });
        this.$message.success("上传成功");
        this.isUpload = false;
      } else {
        this.$message.error("上传失败");
      }
    },
    //文件删除前
    handleBeforeRemove(file, fileList) {
      console.log(file, fileList, "file, fileListfile, fileListfile, fileList");
      this.$refs.files.clearFiles();
      clearInterval(this.uploadTimer);
      this.isUpload = false;

      this.currentFile = {};
      this.$forceUpdate();
    },
    //文件删除
    handleRemove(file, fileList) {
      this.addForm.url = "";
      this.fileList = fileList;
      //this.uploadTimer = null;
      clearInterval(this.uploadTimer);
      this.isUpload = false;

      this.currentFile = {};
      this.$forceUpdate();

    
    },
  },
  beforeDestroy() {
    clearInterval(this.uploadTimer);
  },
};
</script>

<style lang="less">

.newpro .el-progress-bar__inner:before {
  content: "";
  width: 100%;
  height: 100%;
  display: block;
  background-image: repeating-linear-gradient(
    -45deg,
    hsla(0, 0%, 100%, 0.15) 25%,
    transparent 0,
    transparent 50%,
    hsla(0, 0%, 100%, 0.15) 0,
    hsla(0, 0%, 100%, 0.15) 75%,
    transparent 0,
    transparent
  );
  background-size: 40px 40px;
  animation: mymove 2s linear infinite;
}
@keyframes mymove {
  0% {
    background-position: 0;
  }
  25% {
    background-position: 50px;
  }
  50% {
    background-position: 100px;
  }
  75% {
    background-position: 150px;
  }
  100% {
    background-position: 200px;
  }
}
</style>

  • 9
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值