antdv vue upload自定義上傳結(jié)合表單提交方式
antdv vue upload自定義上傳結(jié)合表單提交
表單內(nèi)聯(lián)多個(gè)文件上傳組件
使用antdv的upload組件時(shí)發(fā)現(xiàn)個(gè)怪異的問(wèn)題,上傳文件狀態(tài)每次改變后都會(huì)觸發(fā)change事件,所以上傳成功、失敗、刪除都會(huì)觸發(fā),而怪異的就是刪除后觸發(fā)change,見(jiàn)下圖
就算返回是空的,但只要出發(fā)了change,change都會(huì)默認(rèn)返回如下結(jié)構(gòu)的對(duì)象:
{ file: { /* ... */ }, fileList: [ /* ... */ ] }
也因?yàn)槿绱?,每次表單提交的時(shí)候就算沒(méi)有附件也不會(huì)去校驗(yàn),所以放棄了upload組件的change事件,采用表單的options.getValueFromEvent(因?yàn)槲疫@里有多個(gè)上傳組件,所以多穿了一個(gè)key)
<a-upload name="file" v-decorator="[ 'registerCertificatePath', { rules: [ { required: true, message: '請(qǐng)上傳公司注冊(cè)信息證書(shū)!' } ], getValueFromEvent: e => handleChange(e, 'registerCertificatePath') } ]" :file-list="registerCertificatePathList" :customRequest="file => uploadFile(file, 'registerCertificate')" > <a-button><a-icon type="upload" />上傳</a-button> </a-upload>
定義兩個(gè)方法,重置表單組件setFileList和組件的change回調(diào)handleChange(注意這里不是upload的change)
setFileList(fileKey) { // 根據(jù)filekey值清空指定的上傳文件列表 this[`${fileKey}List`] = []; // 清除對(duì)應(yīng)的表單組件值 this.lastForm.setFieldsValue({ [fileKey]: "" }); }, handleChange({ file, fileList }, key) { if (file.status === "removed" || file.status === "error") { // 當(dāng)這兩種狀態(tài)時(shí)調(diào)用setFileList方法 this.setFileList(key); return ""; } // 給對(duì)應(yīng)的上傳組件文件列表賦值 this[`${key}List`] = fileList; // 賦值給對(duì)應(yīng)表單 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)設(shè)置為 done file.onSuccess(); } else { this.$message.warning(message); // 上傳成功將狀態(tài)設(shè)置為 error file.onError(); } }) .catch(error => { this.$message.error("上傳失?。?); console.log("上傳失?。?, error); // 上傳成功將狀態(tài)設(shè)置為 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="公司注冊(cè)信息證書(shū)"> ? ? ? ? ? ? <a-upload ? ? ? ? ? ? ? name="file" ? ? ? ? ? ? ? v-decorator="[ ? ? ? ? ? ? ? ? 'registerCertificatePath', ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? rules: [ ? ? ? ? ? ? ? ? ? ? { required: true, message: '請(qǐng)上傳公司注冊(cè)信息證書(shū)!' } ? ? ? ? ? ? ? ? ? ], ? ? ? ? ? ? ? ? ? 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íng)業(yè)執(zhí)照附件"> ? ? ? ? ? ? <a-upload ? ? ? ? ? ? ? name="file" ? ? ? ? ? ? ? v-decorator="[ ? ? ? ? ? ? ? ? 'businessLicPath', ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? rules: [{ required: true, message: '請(qǐng)上傳營(yíng)業(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: '請(qǐng)上傳身份證件附件!' }], ? ? ? ? ? ? ? ? ? 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"> ? ? ? ? ? 完成注冊(cè) ? ? ? ? </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: "", // 公司注冊(cè)證書(shū) ? ? ? ? registerCertificatePath: "", // 公司注冊(cè)證書(shū)路徑 ? ? ? ? businessLicName: "", // 營(yíng)業(yè)執(zhí)照附件 ? ? ? ? businessLicPath: "", // 營(yíng)業(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自定義上傳邏輯
其實(shí)用antd自帶的上傳邏輯也行,用自定義的上傳邏輯也行。因?yàn)槲铱偢杏X(jué)有些功能用自帶的上傳邏輯實(shí)現(xiàn)不了,或者實(shí)現(xiàn)起來(lái)比較麻煩,這里就記錄一下自定義上傳邏輯吧!
<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根據(jù)自身情況修改 // 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('服務(wù)器內(nèi)部錯(cuò)誤') }) },
效果:
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
前端vue項(xiàng)目debugger調(diào)試操作詳解
在vue項(xiàng)目調(diào)試的時(shí)候,代碼里面標(biāo)注debugger,這篇文章主要給大家介紹了關(guān)于前端vue項(xiàng)目debugger調(diào)試操作的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2024-05-05通過(guò)vue-cli3構(gòu)建一個(gè)SSR應(yīng)用程序的方法
這篇文章主要介紹了通過(guò)vue-cli3構(gòu)建一個(gè)SSR應(yīng)用程序,以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。2018-09-09vue3+ts 兄弟組件之間傳值的實(shí)現(xiàn)
Vue3是一款流行的前端框架,它支持多種傳值方式,包括兄弟組件之間的傳值,本文主要介紹了vue3+ts 兄弟組件之間傳值的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2023-11-11Vue替代marquee標(biāo)簽超出寬度文字橫向滾動(dòng)效果
這篇文章主要介紹了Vue替代marquee標(biāo)簽超出寬度文字橫向滾動(dòng)效果,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12解決vue接口數(shù)據(jù)賦值給data沒(méi)有反應(yīng)的問(wèn)題
今天小編就為大家分享一篇解決vue接口數(shù)據(jù)賦值給data沒(méi)有反應(yīng)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-08-08淺談Vue.js應(yīng)用的四種AJAX請(qǐng)求數(shù)據(jù)模式
本篇文章主要介紹了淺談Vue.js應(yīng)用的四種AJAX請(qǐng)求數(shù)據(jù)模式,本文將詳細(xì)介紹在Vue應(yīng)用程序中實(shí)現(xiàn)AJAX的四個(gè)方法,有興趣的可以了解一下2017-08-08vue中post請(qǐng)求以a=a&b=b 的格式寫(xiě)遇到的問(wèn)題
這篇文章主要介紹了vue中post請(qǐng)求以a=a&b=b 的格式寫(xiě)遇到的問(wèn)題,需要的朋友可以參考下2018-04-04