vue开发中后台系统复杂表单优化技巧
引言
在中后台系统的日常开发中,表单必不可少,当表单内容比较多,例如有上百个字段(这一点都不夸张,血淋淋的现实)时,代码往往也变得复杂且难以维护,加上各种动态联动的表单校验,无疑让我们的页面开发过程雪上加霜,本文将结合自己平时的开发习惯,分享一下在大表单开发中如何处理复杂的表单校验,以及如何对表单进行拆分,减少单个文件堆积过多的代码内容。
表单校验
<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也会散落在不同的地方,这必然会为后续的代码维护带来困难,接手的人也必须小心翼翼的在上面做修改。
使用computed进行表单校验优化
将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后台系统复杂表单优化的资料请关注猪先飞其它相关文章!
原文出处:https://juejin.cn/post/7033910308057907213
相关文章
- 这篇文章主要介绍了vue中activated的用法,帮助大家更好的理解和使用vue框架,感兴趣的朋友可以了解下...2021-01-03
基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传插件功能
这篇文章主要介绍了基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传插件,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-02-23Antd-vue Table组件添加Click事件,实现点击某行数据教程
这篇文章主要介绍了Antd-vue Table组件添加Click事件,实现点击某行数据教程,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-11-17- 这篇文章主要介绍了Vue基于localStorage存储信息代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-11-16
- 这篇文章主要介绍了vue 实现动态路由的方法,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-06
- 这篇文章主要介绍了vue 监听 Treeselect 选择项的改变操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-01
- 这篇文章主要介绍了Vue组件跨层级获取组件操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-28
- 这篇文章主要介绍了vue 获取到数据但却渲染不到页面上的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-11-19
antdesign-vue结合sortablejs实现两个table相互拖拽排序功能
这篇文章主要介绍了antdesign-vue结合sortablejs实现两个table相互拖拽排序功能,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-01-09vuejs element table 表格添加行,修改,单独删除行,批量删除行操作
这篇文章主要介绍了vuejs element table 表格添加行,修改,单独删除行,批量删除行操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-18- 这篇文章主要介绍了vue treeselect获取当前选中项的label实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-01
- 这篇文章主要给大家介绍了关于Vue中slot-scope的深入理解,这个教程非常适合初学者,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-04-17
- 最常见的多环境配置,就是开发环境配置,和生产环境配置,本文主要介绍了vue项目多环境配置的实现,感兴趣的可以了解一下...2021-07-20
vue项目页面嵌入代码块vue-prism-editor的实现
这篇文章主要介绍了vue项目页面嵌入代码块vue-prism-editor的实现,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-10-30- 这篇文章主要介绍了Vue 3.0 中 jsx 语法使用,帮助大家更好的理解和使用vue框架,感兴趣的朋友可以了解下...2020-11-13
vue Treeselect下拉树只能选择第N级元素实现代码
这篇文章主要介绍了vue Treeselect下拉树只能选择第N级元素实现代码,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-01解决vue的router组件component在import时不能使用变量问题
这篇文章主要介绍了解决vue的router组件component在import时不能使用变量问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-27Ant design vue table 单击行选中 勾选checkbox教程
这篇文章主要介绍了Ant design vue table 单击行选中 勾选checkbox教程,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-10-25- 这篇文章主要为大家详细介绍了vue实现同时设置多个倒计时,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-05-20
- 这篇文章主要介绍了WebStorm无法正确识别Vue3组合式API的解决方案,帮助大家更好的理解和学习使用vue框架,感兴趣的朋友可以了解下...2021-02-18