vue iview上传多文件只发送一次ajax请求,并根据上传进度显示上传进度条

前言
基于iview的上传组件(Upload)以及进度条组件(Progress)

思路
使用Upload组件提供的上传文件之前的钩子,将所有上传文件拦截下来,保存在本地临时数组,使用axios来进行上传
在这里插入图片描述
完整示例

进度条部分,请上传一个大文件来查看效果

<template>
  <Form :model="formData" :label-width="80">
    <FormItem class="upload" label="上传文件">
      <Upload
        :before-upload="handleUpload"
        :action="''"
        :multiple="true"
      >
        <Button icon="ios-cloud-upload-outline">请选择附件</Button>
      </Upload>
      <!-- 进度条 -->
      <Progress v-if="upload.fileProgressShow" :percent="upload.fileProgress" />
      <!-- 显示列表 -->
      <ul>
        <li
          v-for="(item, index) of formData.dispalyFile"
          :key="index"
        >
          <span>{{ item.name }}</span>
          <Icon type="md-close" @click="handleRemove(index)" />
        </li>
      </ul>
    </FormItem>
  </Form>
</template>

<script>
import axios from 'axios';
export default {
  data() {
    return {
      formData: {
        dispalyFile: [] // 临时数组,同时用于显示在页面
      },
      // 上传配置
      upload: {
        look: true, // 控制多文件上传,只触发一次ajax请求
        fileProgressShow: false, // 进度条
        fileProgress: 0 // 进度条进度
      }
    };
  },
  methods: {
    handleUpload(selectFile) {
      // 临时数组,同时用于显示在页面
      this.formData.dispalyFile.push(selectFile)
      // 控制多文件上传,只触发一次ajax请求
      if (this.upload.look) {
        this.upload.look = false;
        // 延迟请求,等待所有文件都从本地读取完毕
        setTimeout(() => {
          let formData = new FormData();
          this.formData.dispalyFile.map(item => {
            // files为后台接收参数
            // []为多文件数组
            formData.append('files[]', item);
          })
          axios.request({
            url: '/upload',
            method: 'post',
            data: formData,
            headers: { 'Content-Type': 'multipart/form-data' },
            onUploadProgress: (progressEvent) => {
              // 用于上传过程中显示进度条
              if (progressEvent.lengthComputable) {
                // 显示进度条
                this.upload.fileProgressShow = true;
                // 计算当前进度
                let curValue = (progressEvent.loaded / progressEvent.total * 100).toFixed(0);
                // 赋值给进度条组件
                this.upload.fileProgress = parseInt(curValue);
              }
            }
          })
            .then(res => {
              // 上传成功处理
              // 隐藏进度条
              this.upload.fileProgressShow = false;
            })
            .catch(() => {
              // 上传失败处理
              // 隐藏进度条
              this.upload.fileProgressShow = false;
            })
        }, 50);
      }
      return false;
    }
  }
};
</script>

<style scoped>
.upload {
  width: 40%;
}
</style>

效果图

上传多文件,只进行了一次ajax请求,这里xlz是一个超大压缩包,用于展示进度条效果, binary 为二进制文件
在这里插入图片描述

如果本篇文章对你有帮助的话,很高兴能够帮助上你。

当然,如果你觉得文章有什么让你觉得不合理、或者有更简单的实现方法又或者有理解不来的地方,希望你在看到之后能够在评论里指出来,我会在看到之后尽快的回复你。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章