> 文章列表 > vue动态表单校验(校验切换)

vue动态表单校验(校验切换)

vue动态表单校验(校验切换)

项目场景:

比如某个统计表单有如下输入项:
1、商品类型(下拉选择框):A类、B类
2、商品补货数量(输入框):输入数字
3、展牌数量(输入框,由商品类型决定是否必填该项):输入1或以上整数

现在要录入补货清单,要求:
1、“商品类型”选择A类时,商品补货数量输入限制:100-300,展牌数量选填
2、“商品类型”选择B类时,商品补货数量输入限制:1-10,展牌数量必填


问题描述

如果用jq的话,可以通过bootstrapValidator提供的方法来动态修改校验规则,例如:

$("#market").bootstrapValidator('removeField','num');//去掉某项校验
$("#rs4850Form").bootstrapValidator('addField','num',{//添加某项校验规则validators:{notEmpty:{message:"必填项不能为空"},regexp:{regexp:/^([1-9]|10)$/,message:"输入的范围为1-10"}}
});

控制el-form校验还需要其他方法。el-form校验规则绑定在rules属性中,例如:

rules:{num:[{required:true,message:"必填项不能为空"},{validator:otherRule}]
}

解决方案:

案例代码:
1、校验:vali.js

let r1 = /^(([1-2]\\d{2})|300)$/;//100-300正则校验
let r2 = /^([1-9]|10)$/;//1-10正则校验
let c1 = /^([1-9]\\d*)$/;//1以上整数正则校验
const reg1 = (rule,value,callback) => {if(value.trim().length == 0){callback(new Error('必填项不能为空!'))} else {r1.test(value) ? callback() : callback(new Error('请输入100-300'))}}
const reg2 = (rule,value,callback) => {if(value.trim().length == 0){callback(new Error('必填项不能为空!'))} else {r2.test(value) ? callback() : callback(new Error('请输入1-10'))}}
const cardReg1 = (rule,value,vallback) => {if(value.trim().length == 0){callback()} else {c1.test(value) ? callback() : callback(new Error('请输入1或以上整数'))}
}
const cardReg2 = (rule,value,vallback) => {if(value.trim().length == 0){callback(new Error('必填项不能为空'))} else {c1.test(value) ? callback() : callback(new Error('请输入1-10'))}
}
export {reg1, reg2, cardReg1, cardReg2}

2、html

<template><div><el-form :model="shop" :rules="rules" ref="shopForm" label-position="left"><el-form-item label="商品类型" prop="type"><el-select v-model="shop.type"><el-option label="A类" value="A"></el-option><el-option label="B类" value="B"></el-option></el-select></el-form-item><el-form-item label="商品补货数量" prop="num"><el-input v-model="shop.num"></el-input></el-form-item><el-form-item label="展牌数量" prop="card"><el-input v-model="shop.card"></el-input></el-form-item></el-form></div>
</template>
<script>
import {reg1, reg2} from "./vali.js";
export default{data(){return {shop:{type:'A',num:'',card:'1'},rules:{num:{validator:reg1}card:{validator:cardReg1}}}},watch:{'shop.num'(n,o){switch(n){case 'A':this.rules.num.validator = reg1;this.rules.card.validator = cardReg1;break;//这里会自动传递rule,value,callbackcase 'B':this.rules.num.validator = reg2;this.rules.card.validator = cardReg2;break;}}}
}
</script>

至此一个简单的案例介绍完成

实际项目中还有更加复杂的需求,比如多个下拉框同时联动,涉及下拉项显示不同的组项,以及某些项是否可选,被联动的下拉项又关联到某些输入框的默认值和校验规则,还有的设计中有“请选择”默认项的(反正本人都遇到过(ˉ▽ˉ;)…),
对于复杂的情况,可以灵活运用watch监听和el-select自带的@change方法:

  1. 比如在@change中绑定了一系列联动校验变化方法,但初始化加数据时,直接拿到后台数据给下拉项赋值是不会触发@change事件的,@change只有在鼠标点击下拉项变化时才能触发。这时,你如果初始化一个“编辑表单”的原数据,就需要通过watch来触发初始化校验对应;
  2. 每次切换校验时,需要对上一次校验结果进行清空this.$refs.shopForm.clearValidate(['num,card']),不然会出现校验文字重叠;
  3. 某些项的校验切换只在一个动态监听中写即可:在watch监听下拉选择变化时更改校验规则(推荐),就不要在@change中同时添加更改校验规则的代码,不然会引起校验两次且有一次不通过的冲突。推荐校验更改放在watch中,也是考虑了表单初始化数据的原因。