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,callback
				case '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中,也是考虑了表单初始化数据的原因。

你可能感兴趣的:(vue.js,前端,elementui)