el-upload用form的方式多文件上传的方法

Posted wang-liang-blogs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了el-upload用form的方式多文件上传的方法相关的知识,希望对你有一定的参考价值。

使用el-upload组件遇到的坑。

1.第一种感觉最好,首先多个文件是一个http请求,另外还可以传除文件外其他的参数,但是没有进度条了。

发送请求的部分没有注释的部分是我分装了调后台的api,注释的部分是直接调。

注意如果使用自定义提交http-request,on-successon-error这两个钩子函数会不起作用,另外点击事件submitUpload中的this.$refs.uploadFiles.submit();是必须的,个人感觉是先将所有的文件给el-form处理,

我发先执行this.$refs.uploadFiles.submit();会多次执行handleUpload函数,次数与要上传文件的个数一样。

fileList: [], files: []要在data中先定义好,file是在form默认有的,是选进来的一个文件。action此时是无用的,但是必须要设置。

<template>
  <el-form>
    <div class="drop-upload-container">
      <el-form-item :label-width="formLabelWidth">
        <el-upload
          multiple
          drag
          ref="uploadFiles"
          :action="action"
          :limit="limit"
          :auto-upload="autoUpload"
          :accept="accept"
          :before-upload="beforeUploadFile"
          :on-remove="handleRemove"
          :on-change="fileChange"
          :on-exceed="exceedFile"
          :http-request="handleUpload"
          :file-list="fileList"
        >
          <i class="el-icon-upload"></i>
          <div class="el-upload__text">
            {{ $t(‘upload.uploadText‘) }}
            <em>{{ $t(‘upload.clickUpload‘) }}</em>
          </div>
          <div class="el-upload__tip" slot="tip">{{ $t(‘upload.uploadFileType‘) }}</div>
        </el-upload>
      </el-form-item>
      <el-form-item class="item-container">
        <el-button
          size="small"
          type="primary"
          @click.native="submitUpload"
        >{{ $t(‘buttonTitle.okTitle‘) }}</el-button>
        <el-button size="small" @click.native="uploadCancle">{{ $t(‘buttonTitle.cancleTitle‘) }}</el-button>
      </el-form-item>
    </div>
  </el-form>
</template>

<script>
import { stringFormat } from "@/utils/stringutils";
import axios from "axios";
import { uploadFilesReq } from "@/api/upload";

export default {
  name: "Upload",
  props: {
    action: {
      required: true,
      type: String
    },
    limit: {
      required: true,
      type: Number
    },
    autoUpload: {
      type: Boolean,
      default: false
    },
    accept: {
      required: true,
      type: String
    }
  },
  data() {
    return {
      formLabelWidth: "80px",
      userIds: sessionStorage.getItem("userid"),
      fileList: [],
      files: []
    };
  },
  methods: {
    // 文件超出个数限制时的钩子
    exceedFile(files, fileList) {
      console.log("===exceed===");
      let limit_num = `${this.limit}`;
      let total_num = `${files.length + fileList.length}`;

      this.$notify.warning({
        title: this.$i18n.t("dialogTitle.dialogWarningTitle"),
        //message: `只能选择 ${this.limit} 个文件,当前共选择了 ${files.length + fileList.length} 个`
        message: stringFormat(
          this.$i18n.t("uploadDialogMsg.uploadFilesLimit"),
          [`${this.limit}`, `${files.length + fileList.length}`]
        )
      });
    },
    // 文件状态改变时的钩子
    fileChange(file, fileList) {
      console.log("===change===");
    },
    // 上传文件之前的钩子, 参数为上传的文件,若返回 false 或者返回 Promise 且被 reject,则停止上传
    beforeUploadFile(file) {
      console.log("before upload");
      console.log(file);
      let extension = file.name.substring(file.name.lastIndexOf(".") + 1);
      const isAcceptFiles =
        extension === "xlsx" ||
        extension === "vue" ||
        extension === "png" ||
        extension === "PNG";
      if (!isAcceptFiles) {
        this.$notify.warning({
          title: this.$i18n.t("dialogTitle.dialogWarningTitle"),
          message: this.$i18n.t("uploadDialogMsg.uploadFilesType")
        });
      }

      let size = file.size / 1024 / 1024;
      const isAcceptSize = size < 10;
      if (!isAcceptSize) {
        this.$notify.warning({
          title: this.$i18n.t("dialogTitle.dialogWarningTitle"),
          message: this.$i18n.t("uploadDialogMsg.uploadFilesSize")
        });
      }
      return isAcceptFiles && isAcceptSize;
    },
    // 点击x时执行的钩子函数
    handleRemove(file, fileList) {
      console.log("===remove===");
    },

    handleUpload(raw) {
      this.files.push(raw.file);
    },
    submitUpload() {
      this.$refs.uploadFiles.submit();
      let fd = new FormData();
      fd.append("userIds", this.userIds);
      this.files.forEach(file => {
        fd.append("file", file, file.name);
      });

      let config = {
        headers: {
          "Content-Type": "multipart/form-data"
        }
      };

      uploadFilesReq(fd, config)
        .then(res => {
          console.log("===upload rep===");
          console.log(res);
          if (res.data.status === "success") {
            this.$notify.success({
              title: this.$i18n.t("dialogTitle.dialogSuccessTitle"),
              message: this.$i18n.t("uploadDialogMsg.uploadFilesSuccess")
            });
          } else {
            this.$notify.error({
              title: this.$i18n.t("dialogTitle.dialogErrorTitle"),
              message: this.$i18n.t("uploadDialogMsg.uploadFilesFailed")
            });
          }
        })
        .catch(err => {
          console.log("===upload error===");
          console.log(err);
          this.$notify.error({
            title: this.$i18n.t("dialogTitle.dialogErrorTitle"),
            message: this.$i18n.t("uploadDialogMsg.uploadFilesFailed")
          });
        });

      // axios
      //   .post("/uploadFiles/pc/job/uploadFile", fd, config, {
      //     timeout: 60000 * 3
      //   })
      //   .then(res => {
      //     if (res.data.status === "success") {
      //       this.$notify.success({
      //         title: this.$i18n.t("dialogTitle.dialogSuccessTitle"),
      //         message: this.$i18n.t("uploadDialogMsg.uploadFilesSuccess")
      //       });
      //     }else{
      //       this.$notify.error({
      //       title: this.$i18n.t("dialogTitle.dialogErrorTitle"),
      //       message: this.$i18n.t("uploadDialogMsg.uploadFilesFailed")
      //     });
      //     }
      //   })
      //   .catch(err => {
      //     this.$notify.error({
      //       title: this.$i18n.t("dialogTitle.dialogErrorTitle"),
      //       message: this.$i18n.t("uploadDialogMsg.uploadFilesFailed")
      //     });
      //   });
    },
    uploadCancle() {
      console.log("===Cancle===");
      this.$refs.uploadFiles.clearFiles();
    }
  }
};
</script>

<style scoped>
.excel-upload-input {
  display: none;
  z-index: -9999;
}
.drop {
  border: 2px dashed #bbb;
  width: 600px;
  /* height: 160px; */
  line-height: 160px;
  margin: 0 auto;
  font-size: 24px;
  border-radius: 5px;
  text-align: center;
  color: #bbb;
  position: relative;
}
.drop-upload-container {
  width: 450px;
}
.item-container {
  margin: 0 auto;
  /* text-align: center; */
  padding-left: 80px;
}
</style>

上传文件调用后台api的封装

import Axios from ‘@/axios‘

export function uploadFilesReq(fd, config) {
  return Axios.post("/uploadFiles/pc/job/uploadFile", fd, config, {
    timeout: 60000 * 3
  });
}

上传文件组件的调用

<template>
  <div class="app-container">
    <upload
    :action="action"
    :limit="limitNum"
    :accept="accept"
    :auto-upload="autoUpload"
    />
  </div>
</template>

<script>
// import Upload from "@/components/Upload";

import Upload from "./upload";

export default {
  name: UploadFiles,
  components: { Upload },
  data() {
    return {
      action: /uploadFiles/pc/job/uploadFile,
      limitNum: 3,
      accept: ".xlsx,.vue,.png,PNG",
      autoUpload: false
    }
  },
  methods: {

  }
}
</script>

2.第二中每个文件都会发送一个请求,并且不能加其他的参数,但是有进度条。

action此时有用的,必须要设置,on-success和on-error这两个钩子函数会起作用

<template>
  <el-form>
    <div class="drop-upload-container">
      <el-form-item :label-width="formLabelWidth">
        <el-upload
          multiple
          drag
          ref="uploadFiles"
          :action="action"
          :limit="limit"
          :auto-upload="autoUpload"
          :accept="accept"
          :before-upload="beforeUploadFile"
          :on-remove="handleRemove"
          :on-change="fileChange"
          :on-exceed="exceedFile"
          :on-success="handleSuccess"
          :on-error="handleError"
          :file-list="fileList"
        >
          <i class="el-icon-upload"></i>
          <div class="el-upload__text">
            {{ $t(‘upload.uploadText‘) }}
            <em>{{ $t(‘upload.clickUpload‘) }}</em>
          </div>
          <div class="el-upload__tip" slot="tip">{{ $t(‘upload.uploadFileType‘) }}</div>
        </el-upload>
      </el-form-item>
      <el-form-item class="item-container">
        <el-button
          size="small"
          type="primary"
          @click.native="submitUpload"
        >{{ $t(‘buttonTitle.okTitle‘) }}</el-button>
        <el-button size="small" @click.native="uploadCancle">{{ $t(‘buttonTitle.cancleTitle‘) }}</el-button>
      </el-form-item>
    </div>
  </el-form>
</template>

<script>
import { stringFormat } from "@/utils/stringutils";
import axios from axios

export default {
  name: "Upload",
  props: {
    action: {
      required: true,
      type: String
    },
    limit: {
      required: true,
      type: Number
    },
    autoUpload: {
      type: Boolean,
      default: false
    },
    accept: {
      required: true,
      type: String
    }
  },
  data() {
    return {
      formLabelWidth: "80px",
      userIds: sessionStorage.getItem("userid"),
      fileList: [],

      files: []
    };
  },
  methods: {
    // 文件超出个数限制时的钩子
    exceedFile(files, fileList) {
      let limit_num = `${this.limit}`;
      let total_num = `${files.length + fileList.length}`;

      this.$notify.warning({
        title: this.$i18n.t("dialogTitle.dialogWarningTitle"),
        message: stringFormat(this.$i18n.t("uploadDialogMsg.uploadFilesLimit"),
          [`${this.limit}`, `${files.length + fileList.length}`]
        )
      });
    },
    // 文件状态改变时的钩子
    fileChange(file, fileList) {
      console.log("===change===");
    },
    // 上传文件之前的钩子, 参数为上传的文件,若返回 false 或者返回 Promise 且被 reject,则停止上传
    beforeUploadFile(file) {
      console.log("before upload");
      console.log(file);
      let extension = file.name.substring(file.name.lastIndexOf(".") + 1);
      const isAcceptFiles =
        extension === "xlsx" ||
        extension === "vue" ||
        extension === "png" ||
        extension === "PNG";
      if (!isAcceptFiles) {
        this.$notify.warning({
          title: this.$i18n.t("dialogTitle.dialogWarningTitle"),
          message: this.$i18n.t("uploadDialogMsg.uploadFilesType")
        });
      }

      let size = file.size / 1024 / 1024;
      const isAcceptSize = size < 10;
      if (!isAcceptSize) {
        this.$notify.warning({
          title: this.$i18n.t("dialogTitle.dialogWarningTitle"),
          message: this.$i18n.t("uploadDialogMsg.uploadFilesSize")
        });
      }
      return isAcceptFiles && isAcceptSize;
    },
    // 点击x时执行的钩子函数
    handleRemove(file, fileList) {
      console.log("===remove===");
    },
    // 文件上传成功时的钩子
    handleSuccess() {
      this.$notify.success({
        title: this.$i18n.t("dialogTitle.dialogSuccessTitle"),
        message: this.$i18n.t("uploadDialogMsg.uploadFilesSuccess")
      });
    },
    // 文件上传失败时的钩子
    handleError(err, file, fileList) {
      this.$notify.error({
        title: this.$i18n.t("dialogTitle.dialogErrorTitle"),
        message: this.$i18n.t("uploadDialogMsg.uploadFilesFailed")
      });
    },
    handleUpload(raw) {
      this.files.push(raw.file);
    },
    submitUpload() {
      console.log(this.form.userIds);
      this.$refs.uploadFiles.submit();
    },
    uploadCancle() {
      console.log("=========uploadFile=========");
      this.$refs.uploadFiles.clearFiles();
    }
  }
};
</script>

<style scoped>
.excel-upload-input {
  display: none;
  z-index: -9999;
}
.drop {
  border: 2px dashed #bbb;
  width: 600px;
  /* height: 160px; */
  line-height: 160px;
  margin: 0 auto;
  font-size: 24px;
  border-radius: 5px;
  text-align: center;
  color: #bbb;
  position: relative;
}
.drop-upload-container {
  width: 450px;
}
.item-container {
  margin: 0 auto;
  /* text-align: center; */
  padding-left: 80px;
}
</style>

以上是关于el-upload用form的方式多文件上传的方法的主要内容,如果未能解决你的问题,请参考以下文章

el-upload多文件上传

vue el-upload上传文件方法 详细解答 action 和 http-request两种方式

el-upload multiple多文件上传,只传上一个的问题

el-upload上传附件-总结

el-upload上传附件-总结

el-upload上传附件-总结