<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在中後臺系統的日常開發中,表單必不可少,當表單內容比較多,例如有上百個欄位(這一點都不誇張,血淋淋的現實)時,程式碼往往也變得複雜且難以維護,加上各種動態聯動的表單校驗,無疑讓我們的頁面開發過程雪上加霜,本文將結合自己平時的開發習慣,分享一下在大表單開發中如何處理複雜的表單校驗,以及如何對錶單進行拆分,減少單個檔案堆積過多的程式碼內容。
<template> <el-form ref="ruleForm" :rules="rules" :model="form" inline > <el-form-item label="企業性質" prop="natureEnterprise"> <el-select v-model="form.natureEnterprise"> <el-option label="國企" :value="1" /> <el-option label="事業單位" :value="2" /> <el-option label="個體戶" :value="3" /> </el-select> </el-form-item> <el-form-item label="業務型別" prop="type"> <el-select v-model="form.type"> <el-option label="護膚" :value="1" /> <el-option label="食品" :value="2" /> </el-select> </el-form-item> <el-form-item label="企業名稱" prop="name"> <el-input v-model="form.name" placeholder="請輸入"></el-input> </el-form-item> <el-form-item label="社會統一信用程式碼" 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: '企業性質不能為空', trigger: 'change' } ], type: [ { required: true, message: '業務型別不能為空', trigger: 'change' } ], address: [ { required: true, message: '註冊地址不能為空', trigger: 'change' } ], name: [ { required: true, message: '企業名稱不能為空', trigger: 'change' } ], creditCode: [ { required: true, message: '社會統一信用程式碼不能為空', trigger: 'change' } ] } } } } </script>
以上表單為例,要求預設全部必填,如果企業性質為個體戶,則註冊地址和社會統一信用程式碼為非必填,讓我們增加以下程式碼來實現這個需求:
watch: { 'form.natureEnterprise': { hanlder(val) { this.rules.creditCode[0].required = val !== 3 this.rules.address[0].required = val !== 3 } } }
如果此時新增一個校驗,假設要求業務型別為護膚時,企業名稱非必填,那我們需要像上面監聽業務型別的值然後做相應的判斷,隨著表單內容的增多,我們的watch會越來越多,同時rules也會散落在不同的地方,這必然會為後續的程式碼維護帶來困難,接手的人也必須小心翼翼的在上面做修改。
將rules作為計算屬性裡的值統一處理,而不是放在data裡,避免需要頻繁去操作data裡的rules,也避免rules的項散落在頁面各處。
computed: { rules({ form }) { // 是否個體戶 const isSelfEmploy = form.natureEnterprise === 3 return { natureEnterprise: [ { required: true, message: '企業性質不能為空', trigger: 'change' } ], type: [ { required: true, message: '業務型別不能為空', trigger: 'change' } ], name: [ { required: true, message: '企業名稱不能為空', trigger: 'change' } ], address: [ { required: !isSelfEmploy, message: '註冊地址不能為空', trigger: 'change' } ], creditCode: [ { required: !isSelfEmploy, message: '社會統一信用程式碼不能為空', trigger: 'change' } ] } } }
改用computed後,會有一個問題:頁面初始載入或computed裡使用的相關值改變時會立即觸發檢驗。看起來體驗不是很好,el-form
有一個validate-on-rule-change
屬性,表示會在rules
屬性改變後立即觸發一次驗證,預設為true,將其設定為false即可
<el-form :validate-on-rule-change="false" ></el-form>
當表單內容變得龐大時,將其塞在一個檔案裡進行開發時無疑會變得很臃腫。這時候我們可以將其拆分成一個一個的元件,每個元件裡獨立負責自己的表單內容以及校驗,最後提交時由父元件統一收集每個子元件的資料進行提交,這樣避免了所有內容都放在一個檔案裡變得大而雜,同時也有利於團隊多人進行開發,減少衝突。
// 父元件:main-form.vue <template> <!-- 子元件-基礎資訊表單 --> <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() { // 呼叫子元件提供的方法,獲取表單資料 const baseFormData = await this.$refs['baseFormRef'].validate() const coopFormData = await this.$refs['coopFormRef'].validate() if (baseFormData && coopFormData) { // 如果校驗通過,拼接子元件資料進行提交 const mainFormData = { ...baseFormData, ...coopFormData } // 提交資料 await saveApi(mainForm) this.$message.success('儲存成功!') } } } } </script>
子元件負責處理自己的內容,同時提供方法給父元件呼叫,在方法裡進行校驗,校驗通過後再返回自身的表單資料給父元件。
// 子元件範例:base-form.vue <template> <el-form ref="ruleForm" :model="form" :rules="rules"> </el-form> </template> <script> export default { data() { return { form: { // ... }, rules: { // ... } } }, methods: { // 提供給父元件的方法並返回表單資料 validate() { return new Promise(resolve => { this.$refs['ruleForm'].validate(valid => { // 校驗通過返回表單資料,反之,返回null if (valid) { resolve(this.form) } else { resolve(null) } }) }) } } } </script>
將大表單拆分後,有些時候兄弟元件間需要通訊,例如coop-form裡的某個欄位需要根據base-form的某個欄位來決定是否必填。我通常選擇使用vuex解決,在base-form的值變化時將其儲存到vuex裡,coop-form則可以從vuex裡獲取,然後進行自己的邏輯處理。
// vuex裡新建檔案用來存放表單通訊資料 // 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) { // 將企業性質的值儲存到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開發中後臺系統複雜表單優化技巧的詳細內容,更多關於vue後臺系統複雜表單優化的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45