多表单提交校验

912 阅读2分钟

1、背景

工作中会遇到用户表单提交,涉及的字段上百个,这种情况下我们一般会拆分组件。
我们使用react或者vue框架的form表单,都自带了校验的功能,如下,调用该方法页面校验不通过的编辑框会变红,并且在对应编辑框附近展示提示语。
如果涉及多个form表单,你会怎样实现同时校验呢?

   checkForm(formName) { 
       this.$refs[formName].validate((valid) => { 
           if (valid) { 
               alert('submit!'); 
           } else { 
               console.log('error submit!!'); 
               return false; 
           } 
       }); 
   }

2、三种实现方式

执行checkForm方法,我们需要对应form渲染,可以拿到对应this.$refs[formName]。

2.1 展示所有dom

  • 存储所有表单的checkForm方法,使用Promise.all执行各个form的校验

缺点:需要渲染所有dom,页面性能不好;一般情况下,我们会使用tabs组件,不同模块放在不同tab

2.2 使用js库async-validate

  • 使用tabs组件,每次只渲染active的tab;
  • 页面数据存在父组件,避免切换tab导致之前编辑数据丢失
  • 通过js库async-validate,找到第一个校验不通过的tab,切到该tab;调用checkForm方法。
import Schema from 'async-validator'

const rules = {
  userName: { type: 'string',required: true },
  pass: { type: 'string',required: true }
}
const validator = new Schema(rules)
var formData  = {userName: '', pass: ''}

validator.validate(formData,(errors, fields) => {
  if (errors) {
    console.log('验证不通过', errors, fields)
    return
  }
  console.log('验证通过')
})

3.3 渲染改动过的tab

接手一个老项目的优化
现状:共有16个页签,每次只渲染active的tab。每个tab的数据独立,都有对应的保存接口;
痛点:每次页签切换都需要点击保存,不然切换页签原编辑数据丢失;点击提交之前,需要逐个点击保存;
需求:切换页签原编辑数据保留;增加总的保存按钮,对需要保存的tab一起保存;
分析:

方案一:展示16个tab,保存时同时执行16个页签的checkForm方法;

  • 缺点:页面开销太大,渲染dom较多;保存时有些页面没编辑不需要保存

方案二:切换tab前执行checkForm方法;

  • 缺点:用户体验不好,必须编辑完当前tab才能切换

方案三:使用js库async-validate;

  • 缺点:代码改动较大,需要提取所有表单的rules和formData对象

方案四:展示所有编辑过的表单

  • 数组cachedList存储所有编辑过的表单;cachedList中非active的tab通过css来隐藏展示,非cachedList的tab不渲染;
  • 切换tab判断当前页面是否编辑过(vue项目可以watch formData;react项目可以使用this.props.form.isFieldTouched或者通过onValuesChange)
  • 如果没有编辑则不存储,否则用 saveMap 存储该tab的保存函数,cachedList存储该tab的key;
  • 点击总的保存按钮,依次执行该saveMap的保存方法,删除校验保存通过的tab数据,并且切换到未校验通过的tab下

欢迎关注我的前端自检清单,我和你一起成长