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.files = [];
       this.$refs.uploadFiles.clearFiles();
       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>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM