form表单验证及相关拓展(动态验证)


一、前言

  最近遇到两个需求,一个是需要对一个表格动态生成的表单项进行校验,还有一个是对动态生成的多个表单进行校验。关于表单的动态校验,这个elementui文档上也有说明传送任意门,其他拓展的没有详细讲解,所以本篇随笔主要是对表单校验进行一个总结,以便后续回顾。

二、普通的表单验证

 这种表单验证官方文档上写的很详细, 只需注意将Form-Item 的 prop 属性设置为需校验的字段名即可。

rules: {
          name: [
            { required: true, message: '请输入活动名称', trigger: 'blur' },
            { min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
          ],
          region: [
            { required: true, message: '请选择活动区域', trigger: 'change' }
          ],
          date1: [
            { type: 'date', required: true, message: '请选择日期', trigger: 'change' }
          ],
          date2: [
            { type: 'date', required: true, message: '请选择时间', trigger: 'change' }
          ],
          type: [
            { type: 'array', required: true, message: '请至少选择一个活动性质', trigger: 'change' }
          ],
          resource: [
            { required: true, message: '请选择活动资源', trigger: 'change' }
          ],
          desc: [
            { required: true, message: '请填写活动形式', trigger: 'blur' }
          ]
        }

 如果默认的校验规则满足不了需求还可以通过validator函数自定义验证规则,例如:

 1 export default {
 2     data() {
 3       var checkAge = (rule, value, callback) => {
 4         if (!value) {
 5           return callback(new Error('年龄不能为空'));
 6         }
 7         setTimeout(() => {
 8           if (!Number.isInteger(value)) {
 9             callback(new Error('请输入数字值'));
10           } else {
11             if (value < 18) {
12               callback(new Error('必须年满18岁'));
13             } else {
14               callback();
15             }
16           }
17         }, 1000);
18       };
19       var validatePass = (rule, value, callback) => {
20         if (value === '') {
21           callback(new Error('请输入密码'));
22         } else {
23           if (this.ruleForm.checkPass !== '') {
24             this.$refs.ruleForm.validateField('checkPass');
25           }
26           callback();
27         }
28       };
29       var validatePass2 = (rule, value, callback) => {
30         if (value === '') {
31           callback(new Error('请再次输入密码'));
32         } else if (value !== this.ruleForm.pass) {
33           callback(new Error('两次输入密码不一致!'));
34         } else {
35           callback();
36         }
37       };
38       return {
39         ruleForm: {
40           pass: '',
41           checkPass: '',
42           age: ''
43         },
44         rules: {
45           pass: [
46             { validator: validatePass, trigger: 'blur' }
47           ],
48           checkPass: [
49             { validator: validatePass2, trigger: 'blur' }
50           ],
51           age: [
52             { validator: checkAge, trigger: 'blur' }
53           ]
54         }
55       };
56     },

以下几点需要注意:

  • 自定义校验规则中不能直接写return,比如if(!value)return;必须返回一个回调函数callback()(返回callback的入参为空代表校验通过规则,返回含new Error(‘自定义提示’)入参代表校验不通过规则。
  • 必须保证自定义校验规则的每个分支都调用了callback方法,否则会导致el-form组件的validate方法无法进入回调函数,就会提交失败。
 1 submitForm(formName) {
 2     //提交表单进行保存校验
 3    this.$refs[formName].validate((valid) => {
 4    if (valid) {
 5      alert('submit!');
 6    } else {
 7       console.log('error submit!!');
 8       return false;
 9    }
10  });
11 },

二、表格动态添加表单校验

   上面动图为表格内嵌入表单动态添加校验,需要注意的点:动态添加的表单项绑定的prop属性需要用scope.$index区分绑定值,否则会导致每一行的绑定值都是一样的;

 

HTML代码

                     
                        
                      
                      
                        
                        
                      
                      
                        
                      
                      
                        
                      
                      
                        
                      
                  

三、多表单的循环校验

需要注意的点:

  1. el-form标签的ref需使用动态属性,如:ref="'xxx'+i"的形式;
  2. 在使用validate方法进行校验的时候,$refs[register][0].validate需要加上[0],因为动态生成的表单ref会变成数组,不加[0]会找不到对应的dom树节点。

HTML代码
资产编号 {{ o.assetLedgerVo.assetCode?o.assetLedgerVo.assetCode:"" }} 资产名称 {{ o.assetLedgerVo.assetName?o.assetLedgerVo.assetName:"" }} S/N号 {{ o.assetLedgerVo.snNum?o.assetLedgerVo.snNum:"" }}

            //注意:model绑定的值必须是一个对象
js代码

ok: function () {
        let self=this
        let data2 = {}
        data2.status='mul';
        let arr=[];//保存验证结果
        let flg = true//
        let mulLength = self.modal.RowSelection.length
        console.log("refs0",self.$refs['dataForm_mul0']);
        console.log("refs1",self.$refs['dataForm_mul1']);
    //循环验证每个表单若有一个表单不符合校验标准则提交失败
        for(let i=0;i {
              if (valid) {
                arr.push('true')
                let data = self.modal.formList
                self.$set(data2,'transferRecordId',self.modal.RowSelection[0].transferRecordId)
                if(i == mulLength-1){
                  arr.forEach(el=>{
                    if(el=='false'){
                      flg = false
                    }
                  })
                  if(flg){
                    self.$emit('model-ok', {data:data,data2:data2}) 
                  }
                }
                    
              }
              else{
                arr.push('false')
                console.log("error");
                return
              }
            })
          }       
      },
vue