如何用vue展示上传文件进度和用时

如何用vue展示上传文件进度和用时

一.代码实现

我们可以用onUploadProgress来实现。

1.1.template

<template>
  <div>
    <fieldset>
      <legend>文件上传</legend>
      <!-- 姓名 -->
      <el-form enctype="multipart/form-data">
        <el-form-item>
          <input type="file" @change="handleFileUpload" />
          <el-button type="submit" @click.prevent="uploadFile">上传</el-button>
        </el-form-item>
        <el-form-item label="上传进度" v-if="progressLoad">
          <el-progress :percentage="percentage"></el-progress>
        </el-form-item>
        <el-form-item label="预计用时" v-if="progressLoad"
          >{{ this.leftTime }}
        </el-form-item>
        <el-form-item label="上传速度" v-if="progressLoad">
          {{ this.speed }}</el-form-item
        >
      </el-form>
    </fieldset>
  </div>
</template>

1.2.script

<script>
export default {
  data() {
    return {
      file: null,
      percentage: 0,
      progressLoad: false,
      speed: 0,
      leftTime: 0,
    };
  },
  methods: {
    async handleFileUpload(event) {
      const file = event.target.files[0];
      this.file = file;
      this.progressLoad = false;
      this.percentage = 0;
    },

    async uploadFile() {
      this.percentage = 0;
      const formData = new FormData();
      formData.append("file", this.file);
      this.progressLoad = true;
      let lastTime = 0; // 上一次计算时间
      let lastSize = 0; // 上一次计算的文件大小
      try {
        const response = await this.$axios.post("/api/upload", formData, {
          onUploadProgress: (progressEvent) => {
            /*验证数据*/
            if (lastTime == 0) {
              lastTime = new Date().getTime();
              lastSize = progressEvent.loaded;
              return;
            }
            /*计算间隔*/

            var nowTime = new Date().getTime();

            var intervalTime = (nowTime - lastTime) / 1000; // 时间单位为毫秒,需转化为秒

            var intervalSize = progressEvent.loaded - lastSize;
            /*重新赋值以便于下次计算*/

            lastTime = nowTime;

            lastSize = progressEvent.loaded;

            /*计算速度*/

            var speed = intervalSize / intervalTime;

            var bSpeed = speed; // 保存以b/s为单位的速度值,方便计算剩余时间
            var units = "b/s"; // 单位名称

            if (speed / 1024 > 1) {
              speed = speed / 1024;

              units = "k/s";
            }

            if (speed / 1024 > 1) {
              speed = speed / 1024;

              units = "M/s";
            }

            /*计算剩余时间*/

            var leftTime =
              (progressEvent.total - progressEvent.loaded) / bSpeed;

            /*计算进度*/

            var progress = parseInt((progressEvent.loaded / progressEvent.total) * 100);
            this.percentage = progress;
            this.speed = speed.toFixed(1) + units;
            this.leftTime = leftTime.toFixed(1) + "秒";
            console.log(
              "当前进度:" +
                progress.toFixed(1) +
                "%    当前速度:" +
                speed.toFixed(1) +
                units +
                "   预计剩余时间:" +
                leftTime.toFixed(1) +
                "秒"
            );
          },
        });
        if (response.data.status == 200) {
          this.$message({
            message: "上传成功",
            type: "success",
            dangerouslyUseHTMLString: true,
          });
        } else {
          this.$message({
            message: "上传失败",
            type: "error",
            dangerouslyUseHTMLString: true,
          });
        }
        this.progressLoad = false;
      } catch (error) {
        console.log(error);
      }
    },
  },
};
</script>

1.3.style

<style scoped>
fieldset {
  /* 表单页面居中,宽度50% ,legend颜色设置,legend圆角*/
  border: 2px solid #dcdfe6;
  text-align: left;
  border-radius: 8px;
  margin: 0 auto;
  width: 50%;
}
</style>

1.4.后端接口

如果想要后端接口请点击如下的连接

SpringtBoot实现文件上传

二.效果

如何用vue展示上传文件进度和用时_第1张图片

你可能感兴趣的:(VUE,vue.js,javascript,前端)