Vue3多文件上传只请求一次(调用一次接口)

3,076 阅读2分钟

Element-plus中使用el-upload 组件进行多文件上传时经常会遇到一个问题,接口会调用多次,这样浪费性能且不符合常理,在使用默认的情况下,多个文件上传是多次调用接口。想要多个文件只调用一个接口,就需要替换掉默认的上传方法。

需求:在使用el-upload多文件上传的时候,只请求一次后端接口。

思路:

1、要知道 el-upload 组件默认是自动上传,首先要取消自动上传,对应的属性 auto-upload:false;

2、需要在确定上传之前,拿到选中的文件流;(最好是选择文件时候出现一个友好弹框这样点击确定的时候可以拿到选中的文件流)

3、实例化一个FormData()对象,循环拿到的多个文件流,append到FormData中;

4、调用上传接口,把FormData传给后端即可;

代码如下:

html代码
    <el-upload
        ref="uploadRef"
        :action="importUrlMore"  //上传接口
        name="file"
        class="model-uploader"
        :show-file-list="false"
        :headers="{ token: getToken() }"  //需要的token
        :data="{ token: getToken() }"
        :on-change="handleChange"   //用change事件获取文件
        accept=".pdf"        //选择文件上传的类型
        :multiple="true"
        :limit="100"     //最多上传100个文件
        :auto-upload="false"  //取消自动上传
      >
        <el-button type="success">发票</el-button>
  </el-upload>

js代码

    let videolist = reactive([]);
    let newList = reactive([]);
    const handleChange = (file, fileList) => {
      videolist = fileList; 
      data.fileList = fileList.map((m) => m.raw);  //我这个文件流是列表里面row字段,可以根据自己的实际情况来
      dialogVisibleOfd.value = true;  //显示弹出框
    };

事件中两个参数分别是当前文件以及选中的多个文件列表,需要考虑到多次文件上传时需要把上一次已经上传的列表清空,所以定义一个变量videolist来接收,上传完成之把这变量赋空

    const ofdsBtnSure = () => {
      const formData = new FormData();  //实例化form对象
      data.fileList.forEach((file) => {
        formData.append('file', file, file.name);   //循环添加到form对象中
      });
      importInvoice(formData).then((response) => {   //调用接口
        if (response.heads && response.heads.code && response.heads.code === 200) {
          ElMessage({
            message: '导入成功',
            type: 'success',
            duration: 3 * 1000
          });
        } else {
          if (response.heads.message) {
            ElMessage({
              message: '导入失败!' + response.heads.message,
              type: 'error',
              duration: 3 * 1000
            });
          }
        }
        videolist.length = 0;   //把已经上传成功的列表清空
        dialogVisibleOfd.value = false;   //关闭弹出框
      });
    };