全手打原創,轉載請標明出處:https://www.cnblogs.com/dreamsqin/p/11529207.html,多謝,=。=~
本文中多表單驗證主要用到Promise.all()實現多任務並行,關於Promise可以看我之前寫的https://www.cnblogs.com/dreamsqin/p/10959411.html,這里不再單獨說明~
先畫個圖看看整個組件+表單的結構(本文列舉4個子組件、子組件中4個子表單為例,更多的同理):
F.vue:父組件,做表單的統一驗證和提交;
X.vue:子組件,單獨做表單驗證,驗證通過則提交表單數據給父組件;
formX:子組件中表單綁定的model變量,通常所有子表單綁定在這一個表單變量上;
form_xn:子表單的ref;
注:本文中表單驗證基於Element-ui實現(采用ref+validate方法實現,但整體框架具備通用性)
一、Promise實例生成
首先需要一個根據ref動態生成Promise實例(可以理解為后面需要並行的任務)的公共方法:
// 根據表單ref,動態生成Promise,參數傳遞ref的name數組 formPromiseArray(vm, formName) { let promiseArray = [] for (var i in formName) { let promise = new Promise(function(resolve, reject) { vm.$refs[formName[i]].validate((valid) => { if (valid) { resolve() } else { reject(new Error()) } }) }) promiseArray.push(promise) } return promiseArray }
二、子組件表單校驗
在子組件中利用Promise.all實現多個子表單並行校驗,只有當所有子表單均通過驗證時才給valid變量賦值為true:
// 表單驗證 async validateForm() { let vm = this let promiseArray = util.formPromiseArray(vm, ['form_a1', ' form_a2', ' form_a3', ' form_a4']) await Promise.all(promiseArray).then(() => { vm.valid = true }).catch(() => { vm.valid = false }) }
三、提交表單數據給父組件
當子組件表單校驗通過后,將最新的表單數據對象返回給父組件:
// 用於父組件觸發,傳遞最新表單數據 async submitForm() { await this.validateForm() if (this.valid) { let form = _.cloneDeep(this.formA) return form } }
四、父組件獲取子組件的表單數據
父組件提交保存請求前校驗子組件表單,當校驗通過時獲取子組件表單數據(父組件中子組件ref為child,通過調用子組件方法獲取表單數據):
// 獲取最新表單數據並封裝成對象,根據是否返回對象確定校驗是否通過 async submitForm() { let form = { recordId: this.recordId } let vm = this await this.$refs.child.submitForm().then(obj => { vm.isPassA = !!obj if (obj) { form.formAData = _.cloneDeep(obj) } }) return form }
五、父組件提交保存請求
當所有表單校驗通過時才提交保存:
// 保存處理進度 save () { let vm = this this.submitForm().then((form) => { if (vm.isPassA && vm.isPassB && vm. isPassC && vm. isPassD) { // 提交保存請求 } else { vm.$message.info('請檢查信息格式') } }) }
至此,整個多表單驗證就完成了,在父組件中還可以根據子組件返回的校驗結果設置子組件表單未通過驗證的樣式,例如小紅點標識。
注:本文中大量使用到了async及await,將會在下一篇博客中詳細說明。