Element|Upload结合Progress实现上传展示进度条

55 篇文章 4 订阅
5 篇文章 0 订阅

背景 :

    项目里的 附件上传 题型组件,用户在上传过程中,如果文件较大,上传过程较慢,而又没有一个类似 Loading... 的加载过程的话,会显得干愣愣的,用户体验较差,所以需要添加一个进度条来提示用户上传的进度,下面有两种方式,一种假的,一种真的,伙伴们可根据需求自行选取实现。

    本文章向大家介绍使用 Upload + Progress 实现文件上传进度条实时更新功能,主要包括使用 Upload + Progress 实现文件上传进度条实时更新功能使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

Upload 上传

通过点击或者拖拽上传文件

Progress 进度条

用于展示操作进度,告知用户当前状态和预期。


“ 简单 && 假 ” 的 进度条 :

利用 setInterval 定时器 模拟实现

<template>
  <div>
    <el-upload
      ref="uploadRef"
      action="#"
      :file-list="fileList"
      :on-change="onChangeData"
      :http-request="handleRequest"
      :before-upload="beforeUpload"
    >
      <el-button v-show="isShowButton" class="btn upload-btn"
        >上传附件</el-button
      >
      <div slot="tip" class="el-upload__tip">上传文件大小不超过50M</div>
    </el-upload>
    <el-progress
      v-show="showProgress"
      :stroke-width="6"
      :percentage="progressPercent"
    ></el-progress>
  </div>
</template>

<script>
import { uploadFileApi } from '@/api';

export default {
  name: 'uploadFile',
  data() {
    return {
      fileType: '', // 文件类型
      fileList: [], // 上传的文件列表
      progressPercent: 0, // 进度条百分比
      isShowButton: false, // 是否显示上传按钮
      showProgress: false, // 是否展示进度条
      isAllowFileTypes: false, // 是否为支持的上传类型
      allowFileTypes: [], // 存储不支持的文件类型
    };
  },
  methods: {
    // 上传的执行方法
    onChangeData(file, fileList) {
      // 前四行代码为了解决:on-change方法第二次调用不起来的问题
      let uploadFilesArr = this.$refs.uploadRef.uploadFiles;
      if (uploadFilesArr.length !== 0) {
        this.$refs.uploadRef.uploadFiles = [];
      }

      let arr = file.name.split('.');
      this.fileType = '.' + arr[arr.length - 1].toLowerCase();
      this.isAllowFileTypes = this.allowFileTypes.includes(this.fileType);
      if (this.isAllowFileTypes) {
        this.isShowButton = false;
        this.fileList = [file];
        if (file.status === 'ready') {
          this.progressPercent = 0;
          this.showProgress = true; // 展示进度条
          const interval = setInterval(() => {
            if (this.progressPercent >= 99) {
              clearInterval();
              return;
            }
            this.progressPercent += 1;
          }, 50);
        }
        if (file.status === 'success') {
          this.progressPercent = 100;
          this.showProgress = false; // 隐藏进度条
        }
      }
    },
    // 文件上传
    async handleRequest(data) {
      let formdata = new FormData();
      formdata.append('file', data.file);
      let res = await uploadFileApi(formdata);
      let { code } = res;
      if (code === '0') {
        // 上传成功
        // ...
      } else if (code === '1') {
        // 上传失败
        this.isShowButton = true;
        this.fileList = [];
      }
    },
    // 上传文件之前的钩子,对文件大小进行校验
    beforeUpload(file) {
      const isLt2M = file.size / 1024 / 1024 < 50;
      if (!isLt2M) {
        this.$message.error('上传文件大小大小不能超过 50MB!');
        return isLt2M;
      }
    },
  },
};
</script>

真实加载的进度条 :

1、使用 Upload + Progress 实现文件上传进度条实时更新功能,需要借助 http-request 属性

具体使用方法如下:

  // 上传的执行方法  
  onChangeData (file, fileList) {
       // 数据小于0.1M的时候按KB显示
      const size = file.size/1024/1024 > 0.1 ? `(${(file.size/1024/1024).toFixed(1)}M)` : `(${(file.size/1024).toFixed(1)}KB)`
      file.name.indexOf('M')>-1 || file.name.indexOf('KB')>-1 ? file.name : file.name += size
  },
  // 文件上传
  handleRequest (data) {
      let formdata = new FormData()
      formdata.append('file', data.file)
      const config = {
        onUploadProgress: progressEvent => {
          // progressEvent.loaded:已上传文件大小
          // progressEvent.total:被上传文件的总大小
          this.progressPercent = Number((progressEvent.loaded / progressEvent.total * 100).toFixed(2))
        }
      }
      this.$axios.post(this.actionURL,formdata,config).then(res => {
        if (res.data.code===1) {}
      })
  },

2、真实进度条,根据文件上传过程中 文件 切片 实现的

<template>
  <div class="uploadBtn">
    <el-upload
      ref="uploadRefs"
      class="upload-demo"
      action=""
      accept="mp4"
      :limit="1"
      :file-list="fileListA"
      :http-request="UploadFileA"
      :on-change="handleChange"
      :on-success="handleSuccess"
    >
      <el-button size="small" type="primary">点击上传</el-button>
    </el-upload>
    <el-progress v-if="uploading" :percentage="uploadPercentage"></el-progress>
  </div>
</template>

<script>
export default {
  name: 'Upload',
  data() {
    return {
      fileListA: [], // 上传的文件列表
      uploading: false, // 是否正在上传
      uploadPercentage: 0, // 进度条百分比
    };
  },
  methods: {
    //上传图片到阿里云
    UploadFileA(file) {
      console.time('executionTime'); //测试文件上传所耗时间开始
      const baseUrl = 'https://你的阿里云地址aliyunUrl.com';
      const fileName = file.file.uid + file.file.name; //文件信息
      const url = baseUrl + '/resource/你的阿里云文件夹地址/' + fileName; //拼接地址
      const xhr = new XMLHttpRequest();
      xhr.upload.addEventListener('progress', (event) => {
        if (event.lengthComputable) {
          const percentage = Math.round((event.loaded * 100) / event.total);
          this.uploadPercentage = percentage; // 给进度条赋值
        }
      });
      xhr.onreadystatechange = () => {
        if (xhr.readyState === XMLHttpRequest.DONE) {
          if (xhr.status === 200 || xhr.status === 201) {
            console.log('阿里云文件', xhr);
            this.formData.fileUrl = xhr.responseURL;
            this.uploadPercentage = 100; // 上传完成后显示100%进度
            console.timeEnd('executionTime'); //测试文件上传所耗时间结束,打印时间为所耗时间,为毫秒级
          } else {
            console.error('上传失败');
          }
          this.uploading = false; // 设置上传状态为 false,隐藏进度条
        }
      };
      this.uploading = true; // 设置上传状态为 true,显示进度条
      this.uploadPercentage = 0; // 设置进度条初始值为0%
      xhr.open('PUT', url, true);
      xhr.send(file.file);
    },
  },
};
</script>

相关参数解答:

    xhr.onreadystatechange 是 XMLHttpRequest 对象的一个事件处理程序,

它在请求状态发生变化时触发。XMLHttpRequest 对象用于与服务器进行异步通信,onreadystatechange 事件在接收到服务器响应并且请求状态发生变化时被触发。
    具体来说,xhr.onreadystatechange 事件在以下几种情况下被触发:
        xhr.readyState 的值发生变化时
        xhr.status 的值发生变化时
        xhr.statusText 的值发生变化时
        xhr.response 的值发生变化时
    xhr.readyState 是 XMLHttpRequest 对象的属性,表示请求的状态。

    它有如下几个可能的值:
        0:未初始化。XMLHttpRequest 对象已创建或已被 abort() 方法重置。
        1:打开。open() 方法已被调用,但 send() 方法未被调用。
        2:发送。send() 方法已被调用,并且头部和状态已经可获得。
        3:接收。正在接收服务器的响应数据。
        4:完成。已经接收到全部响应数据,并且可以在客户端使用了。


    在 xhr.onreadystatechange 事件处理程序中,我们通常使用条件判断来确定请求的状态是否满足特定条件,以执行相应的操作。例如,在上面的代码中,我们检查 xhr.readyState 是否等于 XMLHttpRequest.DONE,来确定请求是否已完成

  如果是,则进一步检查 xhr.status 是否为 200 或 201,来确定请求是否成功。
通过使用 xhr.onreadystatechange 事件处理程序,我们可以根据不同的请求状态来执行相应的逻辑,例如更新页面内容、处理错误等。

    xhr.upload 是 XMLHttpRequest 对象的一个属性,而不是事件处理程序。
    xhr.upload 属性是用于处理上传过程中的事件的。

  它是一个包含了与上传相关事件的 XMLHttpRequestUpload 对象。
        在前面提到的代码中,我们使用了 xhr.upload.addEventListener 方法来注册一个 progress 事件监听器。这个事件监听器用于追踪上传的进度

  • 22
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Element UI 的 el-upload 组件也提供了多个插槽来自定义上传组件的样式,其中包括进度条的样式。你可以通过以下步骤修改 el-upload进度条样式: 1. 在 el-upload 组件中使用 slot="progress" 来自定义进度条的样式,例如: ```html <el-upload class="upload-demo" action="https://jsonplaceholder.typicode.com/posts/" :on-progress="handleProgress" :on-success="handleSuccess" :on-error="handleError" :auto-upload="false" > <el-button slot="trigger" size="small" type="primary">选取文件</el-button> <el-button style="margin-left: 10px;" size="small" type="success" @click="submitUpload">上传到服务器</el-button> <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div> <div slot="progress" class="el-progress"> <div class="el-progress-bar" :style="{width: uploadPercent + '%'}"></div> </div> </el-upload> ``` 2. 在样式表中定义进度条的样式,例如: ```css .el-progress { height: 10px; margin-top: 10px; } .el-progress-bar { height: 100%; background-color: #409eff; transition: width 0.5s ease-in-out; } ``` 在上述样式中,我们将进度条的高度设置为 10px,进度条的背景颜色设置为 #409eff,进度条的宽度变化设置为 0.5s 的过渡效果。 注意:以上代码仅为示例,实际使用时需要根据项目需求进行修改。同时,还需要根据你的上传进度百分比计算出 el-progress-bar 的宽度,并将其赋值给 uploadPercent。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值