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

发布时间:2024年01月11日

背景 :

? ? 项目里的 附件上传 题型组件,用户在上传过程中,如果文件较大,上传过程较慢,而又没有一个类似 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 事件监听器。这个事件监听器用于追踪上传的进度

文章来源:https://blog.csdn.net/weixin_58099903/article/details/135505409
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。