好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

antdv vue upload自定义上传结合表单提交方式

antdv vue upload自定义上传结合表单提交

表单内联多个文件上传组件

使用antdv的upload组件时发现个怪异的问题,上传文件状态每次改变后都会触发change事件,所以上传成功、失败、删除都会触发,而怪异的就是删除后触发change,见下图

就算返回是空的,但只要出发了change,change都会默认返回如下结构的对象:

{
  file: { /* ... */ },
  fileList: [ /* ... */ ]
}

也因为如此,每次表单提交的时候就算没有附件也不会去校验,所以放弃了upload组件的change事件,采用表单的options.getValueFromEvent(因为我这里有多个上传组件,所以多穿了一个key)

<a-upload
  name="file"
  v-decorator="[
    'registerCertificatePath',
    {
      rules: [
        { required: true, message: '请上传公司注册信息证书!' }
      ],
      getValueFromEvent: e =>
        handleChange(e, 'registerCertificatePath')
    }
  ]"
  :file-list="registerCertificatePathList"
  :customRequest="file => uploadFile(file, 'registerCertificate')"
>
  <a-button><a-icon type="upload" />上传</a-button>
</a-upload>

定义两个方法,重置表单组件setFileList和组件的change回调handleChange(注意这里不是upload的change)

setFileList(fileKey) {
  // 根据filekey值清空指定的上传文件列表
  this[`${fileKey}List`] = [];
  // 清除对应的表单组件值
  this.lastForm.setFieldsValue({ [fileKey]: "" });
},
handleChange({ file, fileList }, key) {
  if (file.status === "removed" || file.status === "error") {
    // 当这两种状态时调用setFileList方法
    this.setFileList(key);
    return "";
  }
  // 给对应的上传组件文件列表赋值
  this[`${key}List`] = fileList;
  // 赋值给对应表单
  return file;
}

以下是上传的代码

uploadRequest(param)
 .then(({ success, message, data }) => {
   if (success) {
     const { fileName, filePath } = data;
     this.fileData[`${fileKey}Path`] = filePath;
     this.fileData[`${fileKey}Name`] = fileName;
     this.$message.success(message);
     // 上传成功将状态设置为 done
     file.onSuccess();
   } else {
     this.$message.warning(message);
     // 上传成功将状态设置为 error
     file.onError();
   }
 })
 .catch(error => {
   this.$message.error("上传失败!");
   console.log("上传失败:", error);
   // 上传成功将状态设置为 error
   file.onError();
 });

完整代码:

<template>
? <div class="last">
? ? <a-form
? ? ? :form="lastForm"
? ? ? :label-col="{ span: 10 }"
? ? ? :wrapper-col="{ span: 14 }"
? ? ? @submit="lastSubmit"
? ? >
? ? ? <a-row>
? ? ? ? <a-col :span="8">
? ? ? ? ? <a-form-item label="公司注册信息证书">
? ? ? ? ? ? <a-upload
? ? ? ? ? ? ? name="file"
? ? ? ? ? ? ? v-decorator="[
? ? ? ? ? ? ? ? 'registerCertificatePath',
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? rules: [
? ? ? ? ? ? ? ? ? ? { required: true, message: '请上传公司注册信息证书!' }
? ? ? ? ? ? ? ? ? ],
? ? ? ? ? ? ? ? ? getValueFromEvent: e =>
? ? ? ? ? ? ? ? ? ? handleChange(e, 'registerCertificatePath')
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ]"
? ? ? ? ? ? ? :file-list="registerCertificatePathList"
? ? ? ? ? ? ? :customRequest="file => uploadFile(file, 'registerCertificate')"
? ? ? ? ? ? >
? ? ? ? ? ? ? <a-button><a-icon type="upload" />上传</a-button>
? ? ? ? ? ? </a-upload>
? ? ? ? ? </a-form-item>
? ? ? ? </a-col>
? ? ? ? <a-col :span="8">
? ? ? ? ? <a-form-item label="营业执照附件">
? ? ? ? ? ? <a-upload
? ? ? ? ? ? ? name="file"
? ? ? ? ? ? ? v-decorator="[
? ? ? ? ? ? ? ? 'businessLicPath',
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? rules: [{ required: true, message: '请上传营业执照附件!' }],
? ? ? ? ? ? ? ? ? getValueFromEvent: e => handleChange(e, 'businessLicPath')
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ]"
? ? ? ? ? ? ? :file-list="businessLicPathList"
? ? ? ? ? ? ? :customRequest="file => uploadFile(file, 'businessLic')"
? ? ? ? ? ? >
? ? ? ? ? ? ? <a-button><a-icon type="upload" />上传</a-button>
? ? ? ? ? ? </a-upload>
? ? ? ? ? </a-form-item>
? ? ? ? </a-col>
? ? ? ? <a-col :span="8">
? ? ? ? ? <a-form-item label="身份证件附件">
? ? ? ? ? ? <a-upload
? ? ? ? ? ? ? name="file"
? ? ? ? ? ? ? v-decorator="[
? ? ? ? ? ? ? ? 'idCardCertificatePath',
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? rules: [{ required: true, message: '请上传身份证件附件!' }],
? ? ? ? ? ? ? ? ? getValueFromEvent: e =>
? ? ? ? ? ? ? ? ? ? handleChange(e, 'idCardCertificatePath')
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ]"
? ? ? ? ? ? ? :file-list="idCardCertificatePathList"
? ? ? ? ? ? ? :customRequest="file => uploadFile(file, 'idCardCertificate')"
? ? ? ? ? ? >
? ? ? ? ? ? ? <a-button><a-icon type="upload" />上传</a-button>
? ? ? ? ? ? </a-upload>
? ? ? ? ? </a-form-item>
? ? ? ? </a-col>
? ? ? </a-row>
? ? ? <div class="btn">
? ? ? ? <a-button @click="prev">
? ? ? ? ? 上一步
? ? ? ? </a-button>
? ? ? ? <a-button type="primary" html-type="submit">
? ? ? ? ? 完成注册
? ? ? ? </a-button>
? ? ? </div>
? ? </a-form>
? </div>
</template>

<script>
import { mapState } from "vuex";
import { uploadRequest } from "request/http";
export default {
? computed: {
? ? ...mapState(["oid", "billKey"])
? },
? data() {
? ? return {
? ? ? lastForm: this.$form.createForm(this, { name: "lastForm" }),
? ? ? fileData: {
? ? ? ? registerCertificateName: "", // 公司注册证书
? ? ? ? registerCertificatePath: "", // 公司注册证书路径
? ? ? ? businessLicName: "", // 营业执照附件
? ? ? ? businessLicPath: "", // 营业执照附件路径
? ? ? ? idCardCertificateName: "", // 身份证件附件
? ? ? ? idCardCertificatePath: "" // 身份证件附件路径
? ? ? },
? ? ? registerCertificatePathList: [],
? ? ? businessLicPathList: [],
? ? ? idCardCertificatePathList: []
? ? };
? },
? methods: {
? ? lastSubmit(e) {
? ? ? e.preventDefault();
? ? ? this.lastForm.validateFields((err, values) => {
? ? ? ? if (!err) {
? ? ? ? ? values = this.fileData;
? ? ? ? ? this.$emit("sub", values);
? ? ? ? }
? ? ? });
? ? },
? ? prev() {
? ? ? this.$emit("prev");
? ? },
? ? setFileList(fileKey) {
? ? ? this[`${fileKey}List`] = [];
? ? ? this.lastForm.setFieldsValue({ [fileKey]: "" });
? ? },
? ? handleChange({ file, fileList }, key) {
? ? ? if (file.status === "removed" || file.status === "error") {
? ? ? ? this.setFileList(key);
? ? ? ? return "";
? ? ? }
? ? ? this[`${key}List`] = fileList;
? ? ? return file;
? ? },
? ? uploadFile(file, fileKey) {
? ? ? const formData = new FormData();
? ? ? formData.append("file", file.file);
? ? ? const param = {
? ? ? ? billKey: this.billKey,
? ? ? ? billId: this.oid,
? ? ? ? data: formData
? ? ? };
? ? ? uploadRequest(param)
? ? ? ? .then(({ success, message, data }) => {
? ? ? ? ? if (success) {
? ? ? ? ? ? const { fileName, filePath } = data;
? ? ? ? ? ? this.fileData[`${fileKey}Path`] = filePath;
? ? ? ? ? ? this.fileData[`${fileKey}Name`] = fileName;
? ? ? ? ? ? this.$message.success(message);
? ? ? ? ? ? file.onSuccess();
? ? ? ? ? } else {
? ? ? ? ? ? this.$message.warning(message);
? ? ? ? ? ? file.onError();
? ? ? ? ? }
? ? ? ? })
? ? ? ? .catch(error => {
? ? ? ? ? this.$message.error("上传失败!");
? ? ? ? ? console.log("上传失败:", error);
? ? ? ? ? file.onError();
? ? ? ? });
? ? }
? }
};
</script>

<style lang="less">
.last {
? .ant-upload {
? ? width: 100%;
? ? text-align: left;
? ? .ant-btn{
? ? ? width: 230px;
? ? }
? }
? .ant-upload-list {
? ? text-align: left;
? }
}
</style>

Ant Design Vue自定义上传逻辑

其实用antd自带的上传逻辑也行,用自定义的上传逻辑也行。因为我总感觉有些功能用自带的上传逻辑实现不了,或者实现起来比较麻烦,这里就记录一下自定义上传逻辑吧!

<a-upload
  :action="$rootUrl+'BillAudit/BillFile/UploadFile'"
  :multiple="true"
  :file-list="fileList"
  name="files"
  :customRequest="customRequest"
  :data="{type:3}"
  @change="handleChange"
>
  <a-button> <a-icon type="upload" /> 上传附件 </a-button>
</a-upload>

customRequest方法逻辑

customRequest(data) {
  const formData = new FormData()
  formData.append('files', data.file)
  formData.append('type', 3)
  // 这里的token根据自身情况修改
  // formData.append('token', 'dfjdgfdgskdfkaslfdskf')
  this.saveFile(formData)
},
saveFile(data) {
  axios({
    method: 'post',
    url: this.$rootUrl+'BillAudit/BillFile/UploadFile',
    data: data
  }).then(res=>{
    let fileList = JSON.parse(JSON.stringify(this.fileList))
    if(res.data.code == 1) {
      fileList.map(file=>{
        file.url = res.data.data
        file.status = 'done'
      })
      this.$message.success('上传成功')
    }else {
      fileList.map(file=>{
        file.status = 'error'
      })
      this.$message.error(res.data.message)
    }
    this.fileList = fileList
  }).catch(err=>{
    let fileList = JSON.parse(JSON.stringify(this.fileList))
    fileList.map(file=>{
        file.status = 'error'
      })
      this.fileList = fileList
    this.$message.error('服务器内部错误')
  })
},

效果:

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

查看更多关于antdv vue upload自定义上传结合表单提交方式的详细内容...

  阅读:42次