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

