vue中axios文件上传,可取消,展示进度

import axios from 'axios';

export function uploadFile(url, payload, cancelToken, callback) {
  return new Promise((resolve, reject) => {
    axios({
      method: 'post',
      url,
      data: payload,
      headers: { 'Content-Type': 'multipart/form-data' },
      cancelToken, // 取消事件
      onUploadProgress(progressEvent) {
        // 上传进度条事件
        if (progressEvent.lengthComputable) {
          callback(progressEvent)
        }
      }
    })
      .then(response => {
        resolve(response)
      })
      .catch(error => {
        if (Axios.isCancel(error)) {
          reject(error)
        } else {
          reject(error)
        }
      })
  })
}
// ------------------------------------ 分割线 --------------------------------
// 调用样例

// vue中template部分----------------------
<span class="upload-btn"
        ><input
          id="uploadBillsInp"
          type="file"
          name="file"
          accept=".zip"
          ref="uploadBtn"
          @change="uploadData"
          multiple
          style="display: none;"/>
        <button class="upload-btn-icon" @click="upload"></button
      ></span>

// vue中methods 部分---------------------------------
import axios from 'axios'
// 先引入封装的api
// import {uploadFile} from '上面封装的api的相对路径'

   upload() {
      // 代替执行上传功能
      this.$refs.uploadBtn.click();
    },
   uploadData() {
      this.source = axios.CancelToken.source();

      if (!this.$refs.uploadBtn.files[0]) {
        return;
      }
      Object.values(this.$refs.uploadBtn.files).forEach(item => { // 可以同时上传多个文件
        const obj = {
          fileName: item.name,
          uploadPercent: 0,
        };
        this.fileList.push(obj);
        this.uploadSingleFile(obj, item);
        this.$refs.uploadBtn.value = '';  // 这里将上传input的value清空后就可以重复上传同一文件名的文件
      });
    },
    uploadSingleFile(obj, file) {
      const fileData = new FormData();
      fileData.append('package', file);

      const url = '填写要上传的api地址';
      uploadFile(url, fileData, this.source.token, res => { // 上传进度回调函数
        const loaded = res.loaded;
        const total = res.total;
        this.$nextTick(() => {
          obj.uploadPercent = // 将这个值传递给展示进度的组件中
            Math.floor((loaded / total) * 100) > 1 ? Math.floor((loaded / total) * 100) : 1;
        });
      }).then(
        res => { // 上传成功
          // this.$msg和this.$log是封装的弹窗提示和console, 这里根据自身业务需求来修改
          this.$msg.success('custom-success-message', `${this.cancelFileName}文件上传成功`, 2000);
          this.$log.log('fileUpload.vue -> uploadSingleFile -> success', res.data);
        },
        rej => { // 上传失败
          if (rej.message === 'cancel upload') { // 取消上传
            this.$msg.warn('custom-warn-message', '文件上传取消', 2000);
            this.$log.warn('fileUpload.vue -> uploadSingleFile -> cancel');
          } else { // 其他上传失败报错
            this.$log.error('fileUpload.vue -> uploadSingleFile -> error',  rej);
          }
        }
      );
    },
    cancelRequest(obj) { // 给点击取消的元素绑定上即可 , 取消上传请求
      if (this.source) {
        this.source.cancel('cancel upload'); // 这里传递的什么字符串,在上面的rej.message值就是什么
        obj.uploadPercent = 0;
        const index = this.fileList.findIndex(item => item === obj.fileName);
        this.fileList.splice(index, 1);
      }
    },

你可能感兴趣的:(vue,axios)