vue开发中后台系统复杂表单优化技巧

目录
  • 引言
  • 表单校验
  • 使用computed进行表单校验优化
  • 表单拆分
  • 表单兄弟组件的数据通信问题

引言

在中后台系统的日常开发中,表单必不可少,当表单内容比较多,例如有上百个字段(这一点都不夸张,血淋淋的现实)时,代码往往也变得复杂且难以维护,加上各种动态联动的表单校验,无疑让我们的页面开发过程雪上加霜,本文将结合自己平时的开发习惯,分享一下在大表单开发中如何处理复杂的表单校验,以及如何对表单进行拆分,减少单个文件堆积过多的代码内容。

表单校验

<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后台系统复杂表单优化的资料请关注我们其它相关文章!

(0)

相关推荐

  • Web层改进II-用xmlhttp 无声息提交复杂表单

    xmlhttp是在RIA时代没有来临之前,最能使B/S程序远离每个动作刷新一次页面的痛苦做法,同时也是最平民化的一项技 术,HelloWord几句话就完成了.     不过,大家对xmlhttp的应用大多只以Get方式在URL里传递少数的变量.其实即使是大量数据的Form,,只要用 Javascript稍加封装,,一样可以用简单的用xmlhttp完成提交,真正做到让用家宾至如归,不到页面本身需要刷新的时候 ,决不去刷新用家的界面. 客户端: function xmlhttp_submit(for

  • vue+elementUI 复杂表单的验证、数据提交方案问题

    当我们在做后台管理系统时,经常会遇到非常复杂的表单: 表单项非常多 在各种表单类型下,显示不同的表单项 在某些条件下,某些表单项会关闭验证 每个表单项还会有其他自定义逻辑,比如 输入框可以插入模板变量.输入字符数量显示.图片上传并显示.富文本 ... 在这种错综复杂的情况下,完成表单的验证和提交 可以查看具体例子:例子中省略了很多琐碎的功能,只保留整体的复杂表单框架,用于展示解决方案 方案1: 在一个 vue 文件中 所有的表单项显示隐藏.验证.数据获取.提交.自定义等逻辑放在一起 v-if/v

  • 浅析RxJava处理复杂表单验证问题的方法

    无论是简单的登录页面,还是复杂的订单提交页面,表单的前端验证(比如登录名和密码都符合基本要求才能点亮登录按钮)都是必不可少的步骤.本文展示了如何用RxJava来方便的处理表单提交前的验证问题,例子采用了Android上的一个简单的登录页面 内容提要 传统的验证方式 combineLatest操作符 用combineLatest处理表单验证 combineLatest和zip的区别 本文中所演示的例子sample代码位于RxAndroidDemo,参见loginActivity这个文件 传统的验证

  • ASP中JavaScript处理复杂表单的生成与验证第1/3页

    这里所谓的复杂表单,是指表单中包含多种不同的输入类型,比如下拉列表框.单行文本.多行文本.数值等.在经常需要更换这类表单的场合,需要有一个表单的动态生成程序.本文介绍的正是这样一个系统,它以数据库保存表单定义数据,利用ASP脚本动态生成表单HTML代码以及验证表单输入的脚本. 一.定义数据库表结构 在Web上经常可以看到"每周调查"之类的表单,这就是一种需要经常更新的表单.如果有一个动态生成表单及其验证脚本的程序,可以大大减少制作这些表单的工作量. 在本文的动态表单生成与验证示例中,我

  • vue开发中后台系统复杂表单优化技巧

    目录 引言 表单校验 使用computed进行表单校验优化 表单拆分 表单兄弟组件的数据通信问题 引言 在中后台系统的日常开发中,表单必不可少,当表单内容比较多,例如有上百个字段(这一点都不夸张,血淋淋的现实)时,代码往往也变得复杂且难以维护,加上各种动态联动的表单校验,无疑让我们的页面开发过程雪上加霜,本文将结合自己平时的开发习惯,分享一下在大表单开发中如何处理复杂的表单校验,以及如何对表单进行拆分,减少单个文件堆积过多的代码内容. 表单校验 <template> <el-form r

  • vue中使用vee-validator完成表单校验方案

    前言 由于大部分移动端的组件库都不提供表单校验,因此需要自己封装.目前,使用较多的是async-validator和vee-validator.其中,elementUI组件库提供的表单验证也是基于async-validator,vee-validator是一种基于vue模板的轻量级校验框架.可以根据项目的需求,自行选择合适的方案.本文主要讨论的是vee-validator校验方案. 表单校验的封装 在vue项目中,表单校验是每个前端开发人员都避免不了的需求.校验的好处可以避免无用的 http 请

  • vue中使用element-ui进行表单验证的实例代码

    element-ui 中验证 一.简单逻辑验证(直接使用rules) 实现思路 •html中给el-form增加 :rules="rules" •html中在el-form-item 中增加属性 prop="名称" •js中直接在data中定义rules:{} •html部分 <el-form ref="form" :rules="rules" :model="form" label-width=&q

  • 浅谈vue同一页面中拥有两个表单时,的验证问题

    问题:如果vue的同一个页面拥有两个表单.验证第一个表单时没有通过就切换到第二个,那么第二个表单会出现验证错误的信息 我们可以通过为两个表单添加ref属性 之后在通过调用resetFields()方法来解决问题 代码如下 <el-form :model="form" :rules="rules" ref="form" label-width="100px"> this.$refs["form"]

  • antd+vue实现动态验证循环属性表单的思路

    希望实现查询表单的某些属性可以循环验证必填项: 需求: 1.名称,对比项,备注必填,默认为一行,可增加多行 2.根据名称,动态请求对比项列表,名称变化时,清空该行当前选择的对比项 思路:将整个搜索分成了两个表单,分别去做验证.一个是可动态添加的循环表单form,另一个为普通表单dateForm html <a-form :form="form" @keyup.enter.native='searchQuery'> <div class="dynamic-wr

  • 分享12个Vue开发中的性能优化小技巧(实用!)

    目录 前言 1.长列表性能优化 1.不做响应式 2.虚拟滚动 2.v-for遍历避免同时使用v-if 3.列表使用唯一key 4.使用v-show复用DOM 5.无状态的组件用函数式组件 6.子组件分割 7.变量本地化 8.第三方插件按需引入 9.路由懒加载 10.keep-alive缓存页面 11.事件的销毁 12.图片懒加载 总结 前言 性能优化,是每一个开发者都会遇到的问题,特别是现在越来越重视体验,以及竞争越来越激烈的环境下,对于我们开发者来说,只完成迭代,把功能做好是远远不够的,最重要

  • Vue数据增删改查与表单验证的实现流程介绍

    目录 1. 准备工作 2. 弹出窗口 3. 新增更新功能 4. 删除功能 5. 表单验证 6. 接口文档 1. 准备工作 后台服务接口,对书本的增删改查操作 2. 弹出窗口 进入ElementUi官网, 找到Dialog对话框,可以参考“嵌套表单的dialog”实现. 该步骤先实现弹出窗口的前端逻辑,并不会调用后台接口服务进行实际的业务操作. BookList.vue <!-- 弹出窗口:增加和修改书本信息共用一个弹出窗口,需要根据用户的选择动态的设置弹出窗口的标题 :tile 通过绑定值的方式

  • Python中使用django form表单验证的方法

    一. django form表单验证引入 有时时候我们需要使用get,post,put等方式在前台HTML页面提交一些数据到后台处理例 ; <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Form</title> </head> <body> <div> <for

  • Vue+Element实现动态生成新表单并添加验证功能

    首先有一个这样的需求,表单中默认有一个联系人信息,用户可以再添加新的联系人信息 点击添加更多联系人之后 官方文档中有写用v-for来实现新增表单,但是那是单表单的新增,现在多表单的新增,可以考虑的实现方法是先写死一个必须的表单,需要新增的两个表单放在一个div里,在div中使用v-for生成,达到同时新增的效果 代码如下 //必填一个联系人的表单 <el-form-item class="rules" label="通知对象:" prop="noti

  • 详解vue开发中调用微信jssdk的问题

    起因 微信分享网址时无法分享图片,这个问题需要用jssdk去解决.其实开始的时候时可以看到图片的,但后来微信禁止了.所以只能使用jssdk去解决. 普通网页开发很简单,但是使用vue或其他前端框架开发spa单页面webapp的时候就会有问题了.只要url发生变化就会报签名错误.其实微信官方上已经写了说明. 所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支

随机推荐