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函数中执行;
以上为动态校验总结。
这两篇内容详细记录了我遇到的,以及所有能想到的前端校验的情况的相关内容,欢迎补充。