antdv vue upload自定義上傳結合表單提交方式
antdv vue upload自定義上傳結合表單提交
表單內聯多個文件上傳組件
使用antdv的upload組件時發(fā)現個怪異的問題,上傳文件狀態(tài)每次改變后都會觸發(fā)change事件,所以上傳成功、失敗、刪除都會觸發(fā),而怪異的就是刪除后觸發(fā)change,見下圖


就算返回是空的,但只要出發(fā)了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") {
// 當這兩種狀態(tài)時調用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);
// 上傳成功將狀態(tài)設置為 done
file.onSuccess();
} else {
this.$message.warning(message);
// 上傳成功將狀態(tài)設置為 error
file.onError();
}
})
.catch(error => {
this.$message.error("上傳失??!");
console.log("上傳失?。?, error);
// 上傳成功將狀態(tài)設置為 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="營業(yè)執(zhí)照附件">
? ? ? ? ? ? <a-upload
? ? ? ? ? ? ? name="file"
? ? ? ? ? ? ? v-decorator="[
? ? ? ? ? ? ? ? 'businessLicPath',
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? rules: [{ required: true, message: '請上傳營業(yè)執(zhí)照附件!' }],
? ? ? ? ? ? ? ? ? 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: "", // 營業(yè)執(zhí)照附件
? ? ? ? businessLicPath: "", // 營業(yè)執(zhí)照附件路徑
? ? ? ? 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('服務器內部錯誤')
})
},效果:

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

