js-动态表单校验-吐血总结最近遇到的变态表单校验2—element+原生

  • 2021 年 6 月 25 日
  • 筆記

上一部分总结了基础常用的js表单校验,包括原生以及框架,下面来总结这一个月涉及到的动态校验:

动态表单校验大致分为三种情况:

1. 首先是固定校验规则,但是表单组件是动态生成的,例如:在表单或者表格里有“增加”功能,增加一行,给新生成的表单组件添加校验规则。

2. 第二类就是组件固定,但是校验规则会随着其他条件的变化而变化,例如:基本的最常见的例子是确认密码的校验,判断第二次输入的密码与第一次输入是否一致。

3. 最后,比较复杂的就是以上两类情况的混合情况,动态生成的表单,且校验规则也是动态变化的。

接下来还是用最直观的举例子来解释用法:

  这里使用了element自带的rules,其他框架同理,也可以自己绑定方法,原生的用blur,focus等也可以

一:固定校验规则+组件动态生成

要实现的效果:点击第一行的新增生成下面的表格,表格各自校验

实现方法代码举例:

html :(放到表格里的组件,和表单同理)

1 <el-table-column align="center" label="金额标准" prop="level">
2     <template slot-scope="scope">
3         <span v-if="scope.row.edit">{{ scope.row.level}}</span>
4         <el-form-item v-show="!scope.row.edit" :prop="'list.'+scope.$index+'.level'" :rules="rules.level">
5             <el-input v-model="scope.row.level" autofocus placeholder="请输入金额标准"></el-input>
6         </el-form-item>
7     </template>
8 </el-table-column>

js :(校验规则以及触发方式定义)

 1 data() {
 2  return {
 3    rules:{
 4     level: [
 5        {required: true, message: '请输入金额标准', trigger: ['blur', 'change']},
 6        { validator:function(rule,value,callback){
 7          if(/^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(Number(value)) == false||Number(value)>10000){
 8            callback(new Error("请输入数字,可保留两位小数,最大不超过10000"));
 9          }else if(/^(([1-9][0-9]*)|(([0]\.\d{1,2}|[1-9][0-9]*\.\d{1,2})))$/.test(Number(value)) == false){
10            callback(new Error("请输入数字,可保留两位小数,最大不超过10000"));
11          }else{
12            callback();
13          }
14        }, trigger:['blur', 'change']
15      }],
17    }
18  }
19 }        

js:(实现方式)

 1 formValidate(formName){
 2      this.$refs[formName].validate((valid) => {
 3          if(valid) {
 4             this.validateForm=true;
 5          }else{
 6             this.$message.warning("请确认输入信息无误!");
 7             this.validateForm=false;
 8          }
 9     });
10     return this.validateForm;
11  }

调用formValidate方法即可。

 

二:固定组件+动态校验规则

要实现的效果:(element官方举例)

实现方法代码举例:

html:

1 <el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm">
2   <el-form-item label="密码" prop="pass">
3     <el-input type="password" v-model="ruleForm.pass" autocomplete="off"></el-input>
4   </el-form-item>
5   <el-form-item label="确认密码" prop="checkPass">
6     <el-input type="password" v-model="ruleForm.checkPass" autocomplete="off"></el-input>
7   </el-form-item>
8 </el-form>

 

js:(校验规则可以定义到return之前,也可以直接放到rules里)

 1 data() {
 2       var validatePass = (rule, value, callback) => {
 3         if (value === '') {
 4           callback(new Error('请输入密码'));
 5         } else {
 6           if (this.ruleForm.checkPass !== '') {
 7             this.$refs.ruleForm.validateField('checkPass');
 8           }
 9           callback();
10         }
11       };
12       var validatePass2 = (rule, value, callback) => {
13         if (value === '') {
14           callback(new Error('请再次输入密码'));
15         } else if (value !== this.ruleForm.pass) {
16           callback(new Error('两次输入密码不一致!'));
17         } else {
18           callback();
19         }
20       };
21       return {
22         ruleForm: {
23           pass: '',
24           checkPass: ''
25         },
26         rules: {
27           pass: [
28             { validator: validatePass, trigger: 'blur' }
29           ],
30           checkPass: [
31             { validator: validatePass2, trigger: 'blur' }
32           ]
33         }
34       };

 

 

三:动态生成组件+动态校验规则

要实现的效果:三个组件分别纵向对比校验,各组件个数不固定,为动态生成,各自校验规则也相互影响,人数2依附于人数1的输入值。

    

实现方法代码举例:

html:(绑定prop以及rules)

 1<tr>
 2  <td>
 3    <div>
 4      <div><label class="col-sm-4 control-label addbefore">天数</label></div>
 6    </div>
 7  </td>
 8  <td>
 9    <div>
10      <template v-for="(item, index) in form.list1">
11        <el-form-item
12          :key="item.key"
13          :id="item.key"
14          :name="item.key"
15          style="float: left;"
16          :prop="'list1.' + index +'.a_value'"
17          :rules="rules.a_value1">
18          <el-input v-model.number="item.a_value"></el-input><span></span>
20        </el-form-item>
21      </template>
22    </div>
23  </td>
24 </tr>
25<tr>
26  <td>
27    <div><label>人数1</label></div>
30  </td>
31  <td>
32    <div>
33      <template v-for="(domain, index) in form.list2">
34        <el-form-item
35          :key="domain.key"
36          :id="domain.key"
37          :name="domain.value"
38          style="float: left;"
39          :prop="'list2.' + index +'.b_value'"
40          :rules="rules.b_value">
41          <el-input v-model.number="domain.b_value"></el-input><span></span>
43        </el-form-item>
44      </template>
45    </div>
46  </td>
47</tr>
48<tr>
49  <td>
50    <div><label>人数2</label></div>
56  </td>
57  <td>
58    <div>
59      <template v-for="(domain, index) in form.list3">
60        <el-form-item
61          :key="domain.key"
62          :id="domain.key"
63          :name="domain.value"
64          style="float: left;"
65          :prop="'list3.' + index +'.c_value'"
66          :rules="rules.c_value">
67          <el-input v-model.number="domain.c_value"></el-input><span></span>
69        </el-form-item>
70      </template>
71    </div>
72  </td>
73</tr>

 js :(数据及校验规则定义)

 1 data(){
 2     var me=this
 3     return {
 4         form:{
 5             list1:[],
 6             list2:[],
 7             list3:[]
 8         }
 9         rlues:{
10               a_value: [
11                             { required: true, message: '请输入', trigger: ['blur', 'change'] },
12                             { type: 'number', message: '请输入数字', trigger: ['blur', 'change']},
13                             {
14                                 validator: (rule, value, callback) => {
15                                     if (value > 200) {
16                                         callback(new Error('天数应小于200'))
17                                     } else {
18                                         callback()
19                                     }
20                                 },
21                                 trigger: ['blur', 'change']
22                             }
23                         ],
24                 b_value:[
25                             { required: true, message: '请输入', trigger: ['blur', 'change'] },
26                             { type: 'number', message: '请输入数字', trigger: ['blur', 'change']},
27                             {
28                                 validator: (rule, value, callback) => {
29                                     if (value > 100) {
30                                         callback(new Error('人数1应小于100'))
31                                     } else {
32                                         callback()
33                                     }
34                                 },
35                                 trigger: ['blur', 'change']
36                             }
37                         ],
38                  c_value:[
39                             { required: true, message: '请输入', trigger: ['blur', 'change'] },
40                             { type: 'number', message: '请输入数字', trigger: ['blur', 'change']},
41                             {
42                                 validator: (rule, value, callback) => {
43                                     let index=Number(rule.field.substr(6, 1))
44                                     let sc=(me.form.list2[index].b_value)*0.1
45                                     if (value > sc) {
46                                         callback(new Error('人数2不超过人数1的10%'))
47                                     } else {
48                                         callback()
49                                     }
50                                 },
51                                 trigger: ['blur', 'change']
52                             }
53                         ]
54                 }
55         }
56 }

 

 js:(实现方式)

 1 formValidate(formName){
 2  this.$refs[formName].validate((valid) => {
 3    if(valid) {
 4       this.validateForm=true;
 5    }else{
 6      this.$message.warning("请确认输入信息无误!");
 7      this.validateForm=false;
 8    }
 9  });
10  return this.validateForm;
11}

总结:

这三种情况其实基本原理是相同的,即是在变化的元素以及变化的标准怎么比较,首先来说确定两点,一是要绑定prop,动态双向绑定,相当于生成组件是时给该元素生成一个标识,一般来说动态绑定写法如下:

      :prop=”‘list.’ + index +’.value'” 

       或者写成
    :prop=”‘list.’+scope.$index+’.value‘”  

 

其次,是绑定一个规则:

    :rules=”rules.value”

然后就是具体校验,可以写到html里,也可以写到js里,一般来说有校验方法的写到js里,需要注意的是 validator: (rule, value, callback) => { },这个回调方法里的三个参数:

  第一个参数 rule,为绑定元素的prop,主要用来取到需要进行比较的值,即规则;

  第二个参数 value,为此时输入的内容,和规则作比较,是否符合;

  第三个参数 callback,为校验完的回调函数,校验成功或失败的提示在callback函数中执行;

 

以上为动态校验总结。

这两篇内容详细记录了我遇到的,以及所有能想到的前端校验的情况的相关内容,欢迎补充。