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代码
//封装的下拉框组件,用来实现与资产类别的下拉框内容联动
三、多表单的循环校验
需要注意的点:
- el-form标签的ref需使用动态属性,如:ref="'xxx'+i"的形式;
- 在使用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
}
})
}
},