vue開(kāi)發(fā)中后臺(tái)系統(tǒng)復(fù)雜表單優(yōu)化技巧
引言
在中后臺(tái)系統(tǒng)的日常開(kāi)發(fā)中,表單必不可少,當(dāng)表單內(nèi)容比較多,例如有上百個(gè)字段(這一點(diǎn)都不夸張,血淋淋的現(xiàn)實(shí))時(shí),代碼往往也變得復(fù)雜且難以維護(hù),加上各種動(dòng)態(tài)聯(lián)動(dòng)的表單校驗(yàn),無(wú)疑讓我們的頁(yè)面開(kāi)發(fā)過(guò)程雪上加霜,本文將結(jié)合自己平時(shí)的開(kāi)發(fā)習(xí)慣,分享一下在大表單開(kāi)發(fā)中如何處理復(fù)雜的表單校驗(yàn),以及如何對(duì)表單進(jìn)行拆分,減少單個(gè)文件堆積過(guò)多的代碼內(nèi)容。
表單校驗(yàn)
<template> <el-form ref="ruleForm" :rules="rules" :model="form" inline > <el-form-item label="企業(yè)性質(zhì)" prop="natureEnterprise"> <el-select v-model="form.natureEnterprise"> <el-option label="國(guó)企" :value="1" /> <el-option label="事業(yè)單位" :value="2" /> <el-option label="個(gè)體戶" :value="3" /> </el-select> </el-form-item> <el-form-item label="業(yè)務(wù)類型" prop="type"> <el-select v-model="form.type"> <el-option label="護(hù)膚" :value="1" /> <el-option label="食品" :value="2" /> </el-select> </el-form-item> <el-form-item label="企業(yè)名稱" prop="name"> <el-input v-model="form.name" placeholder="請(qǐng)輸入"></el-input> </el-form-item> <el-form-item label="社會(huì)統(tǒng)一信用代碼" prop="creditCode"> <el-input v-model="form.creditCode" placeholder="請(qǐng)輸入"></el-input> </el-form-item> <el-form-item label="注冊(cè)地址" prop="address"> <el-input v-model="form.address" placeholder="請(qǐng)輸入"></el-input> </el-form-item> </el-form> </template> <script> export default { data() { return { form: { natureEnterprise: null, type: null, address: '', name: '', creditCode: '' }, rules: { natureEnterprise: [ { required: true, message: '企業(yè)性質(zhì)不能為空', trigger: 'change' } ], type: [ { required: true, message: '業(yè)務(wù)類型不能為空', trigger: 'change' } ], address: [ { required: true, message: '注冊(cè)地址不能為空', trigger: 'change' } ], name: [ { required: true, message: '企業(yè)名稱不能為空', trigger: 'change' } ], creditCode: [ { required: true, message: '社會(huì)統(tǒng)一信用代碼不能為空', trigger: 'change' } ] } } } } </script>
以上表單為例,要求默認(rèn)全部必填,如果企業(yè)性質(zhì)為個(gè)體戶,則注冊(cè)地址和社會(huì)統(tǒng)一信用代碼為非必填,讓我們?cè)黾右韵麓a來(lái)實(shí)現(xiàn)這個(gè)需求:
watch: { 'form.natureEnterprise': { hanlder(val) { this.rules.creditCode[0].required = val !== 3 this.rules.address[0].required = val !== 3 } } }
如果此時(shí)新增一個(gè)校驗(yàn),假設(shè)要求業(yè)務(wù)類型為護(hù)膚時(shí),企業(yè)名稱非必填,那我們需要像上面監(jiān)聽(tīng)業(yè)務(wù)類型的值然后做相應(yīng)的判斷,隨著表單內(nèi)容的增多,我們的watch會(huì)越來(lái)越多,同時(shí)rules也會(huì)散落在不同的地方,這必然會(huì)為后續(xù)的代碼維護(hù)帶來(lái)困難,接手的人也必須小心翼翼的在上面做修改。
使用computed進(jìn)行表單校驗(yàn)優(yōu)化
將rules作為計(jì)算屬性里的值統(tǒng)一處理,而不是放在data里,避免需要頻繁去操作data里的rules,也避免rules的項(xiàng)散落在頁(yè)面各處。
computed: { rules({ form }) { // 是否個(gè)體戶 const isSelfEmploy = form.natureEnterprise === 3 return { natureEnterprise: [ { required: true, message: '企業(yè)性質(zhì)不能為空', trigger: 'change' } ], type: [ { required: true, message: '業(yè)務(wù)類型不能為空', trigger: 'change' } ], name: [ { required: true, message: '企業(yè)名稱不能為空', trigger: 'change' } ], address: [ { required: !isSelfEmploy, message: '注冊(cè)地址不能為空', trigger: 'change' } ], creditCode: [ { required: !isSelfEmploy, message: '社會(huì)統(tǒng)一信用代碼不能為空', trigger: 'change' } ] } } }
改用computed后,會(huì)有一個(gè)問(wèn)題:頁(yè)面初始加載或computed里使用的相關(guān)值改變時(shí)會(huì)立即觸發(fā)檢驗(yàn)??雌饋?lái)體驗(yàn)不是很好,el-form
有一個(gè)validate-on-rule-change
屬性,表示會(huì)在rules
屬性改變后立即觸發(fā)一次驗(yàn)證,默認(rèn)為true,將其設(shè)置為false即可
<el-form :validate-on-rule-change="false" ></el-form>
表單拆分
當(dāng)表單內(nèi)容變得龐大時(shí),將其塞在一個(gè)文件里進(jìn)行開(kāi)發(fā)時(shí)無(wú)疑會(huì)變得很臃腫。這時(shí)候我們可以將其拆分成一個(gè)一個(gè)的組件,每個(gè)組件里獨(dú)立負(fù)責(zé)自己的表單內(nèi)容以及校驗(yàn),最后提交時(shí)由父組件統(tǒng)一收集每個(gè)子組件的數(shù)據(jù)進(jìn)行提交,這樣避免了所有內(nèi)容都放在一個(gè)文件里變得大而雜,同時(shí)也有利于團(tuán)隊(duì)多人進(jìn)行開(kāi)發(fā),減少?zèng)_突。
// 父組件:main-form.vue <template> <!-- 子組件-基礎(chǔ)信息表單 --> <base-form ref="baseFormRef" /> <!-- 子組件-合作信息表單 --> <coop-form ref="coopFormRef" /> <el-button type="primary" @click="handleSave">保存</el-button> </template> <script> import BaseForm from './base-form' import CoopForm from './coop-form' export default { components: { BaseForm, CoopForm }, methods: { async handleSave() { // 調(diào)用子組件提供的方法,獲取表單數(shù)據(jù) const baseFormData = await this.$refs['baseFormRef'].validate() const coopFormData = await this.$refs['coopFormRef'].validate() if (baseFormData && coopFormData) { // 如果校驗(yàn)通過(guò),拼接子組件數(shù)據(jù)進(jìn)行提交 const mainFormData = { ...baseFormData, ...coopFormData } // 提交數(shù)據(jù) await saveApi(mainForm) this.$message.success('保存成功!') } } } } </script>
子組件負(fù)責(zé)處理自己的內(nèi)容,同時(shí)提供方法給父組件調(diào)用,在方法里進(jìn)行校驗(yàn),校驗(yàn)通過(guò)后再返回自身的表單數(shù)據(jù)給父組件。
// 子組件示例:base-form.vue <template> <el-form ref="ruleForm" :model="form" :rules="rules"> </el-form> </template> <script> export default { data() { return { form: { // ... }, rules: { // ... } } }, methods: { // 提供給父組件的方法并返回表單數(shù)據(jù) validate() { return new Promise(resolve => { this.$refs['ruleForm'].validate(valid => { // 校驗(yàn)通過(guò)返回表單數(shù)據(jù),反之,返回null if (valid) { resolve(this.form) } else { resolve(null) } }) }) } } } </script>
表單兄弟組件的數(shù)據(jù)通信問(wèn)題
將大表單拆分后,有些時(shí)候兄弟組件間需要通信,例如coop-form里的某個(gè)字段需要根據(jù)base-form的某個(gè)字段來(lái)決定是否必填。我通常選擇使用vuex解決,在base-form的值變化時(shí)將其保存到vuex里,coop-form則可以從vuex里獲取,然后進(jìn)行自己的邏輯處理。
// vuex里新建文件用來(lái)存放表單通信數(shù)據(jù) // src/store/modules/formDta.js export default { namespaced: true, state: { natureEnterprise: '' }, mutations: { SET_NATURE_ENTERPRISE(state, payload) { state.natureEnterprise = payload } } } // src/store/index.js import Vue from 'vue' import Vuex from 'vuex' import formData from './modules/formData.js' Vue.use(Vuex) export default new Vuex.Store({ modules: { formData } })
// base-form.vue watch: { 'form.natureEnterprise': { handler(val) { // 將企業(yè)性質(zhì)的值存儲(chǔ)到vuex里 this.$store.commit('formData/SET_NATURE_ENTERPRISE', val) } } }
// coop-form.vue computed: { ...mapState('formData', [ 'natureEnterprise' ]), rules() { return { address: [ { required: this.natureEnterprise === 1, message: '注冊(cè)地址不能為空', trigger: 'change' } ] } } }
以上就是vue開(kāi)發(fā)中后臺(tái)系統(tǒng)復(fù)雜表單優(yōu)化技巧的詳細(xì)內(nèi)容,更多關(guān)于vue后臺(tái)系統(tǒng)復(fù)雜表單優(yōu)化的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Vue中$bus的用法及$on、$off的使用說(shuō)明
這篇文章主要介紹了Vue中$bus的用法及$on、$off的使用說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05在vue中給列表中的奇數(shù)行添加class的實(shí)現(xiàn)方法
今天小編就為大家分享一篇在vue中給列表中的奇數(shù)行添加class的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09vue + element-ui實(shí)現(xiàn)簡(jiǎn)潔的導(dǎo)入導(dǎo)出功能
Element-UI是餓了么前端團(tuán)隊(duì)推出的一款基于Vue.js 2.0 的桌面端UI框架,手機(jī)端有對(duì)應(yīng)框架是 Mint UI,下面這篇文章主要給大家介紹了關(guān)于利用vue + element-ui如何實(shí)現(xiàn)簡(jiǎn)潔的導(dǎo)入導(dǎo)出功能的相關(guān)資料,需要的朋友可以參考下。2017-12-12使用Vue.js實(shí)現(xiàn)數(shù)據(jù)的雙向綁定
在Vue.js中,雙向數(shù)據(jù)綁定是一項(xiàng)非常強(qiáng)大的功能,它能夠使數(shù)據(jù)和視圖之間保持同步,讓開(kāi)發(fā)者更加方便地操作數(shù)據(jù),在本文中,我們將介紹如何用Vue.js實(shí)現(xiàn)數(shù)據(jù)的雙向綁定,需要的朋友可以參考下2023-04-04基于VUE移動(dòng)音樂(lè)WEBAPP跨域請(qǐng)求失敗的解決方法
這篇文章主要介紹了基于VUE移動(dòng)音樂(lè)WEBAPP跨域請(qǐng)求失敗的解決方法,需要的朋友可以參考下2018-01-01關(guān)于Vue新搭檔TypeScript快速入門實(shí)踐
這篇文章主要介紹了關(guān)于Vue新搭檔TypeScript快速入門實(shí)踐,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09關(guān)于element-ui的隱藏組件el-scrollbar的使用
這篇文章主要介紹了關(guān)于element-ui的隱藏組件el-scrollbar的使用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-05-05