手摸手一起自定义表单验证(包括输入校验及提交校验)

环境uniapp、vue。其他环境也可,对应小改即可
样式大概长这样:
在这里插入图片描述

一、先写个校验方法吧

export default {
	error: {},
	check : function (data, rule){
		let result = true
		for(var i = 0; i < rule.length; i++){
			if (!rule[i].checkType){result = false;}
			if (!rule[i].name) {result = false;}
			if (!rule[i].errorMsg) {result = false;}
			if (!data[rule[i].name]) {this.error[rule[i].name] = rule[i].errorMsg; result = false;}
			switch (rule[i].checkType){
				case 'string':
					var reg = new RegExp('^.{' + rule[i].checkRule + '}$');
					if(!reg.test(data[rule[i].name])) { this.error[rule[i].name] = rule[i].errorMsg; result = false; } else { this.error[rule[i].name] = ''; }
				break;
				case 'reg':
					var reg = new RegExp(rule[i].checkRule);
					console.log(23)
					if (!reg.test(data[rule[i].name])) { this.error[rule[i].name] = rule[i].errorMsg; result = false; } else { this.error[rule[i].name] = ''; }
				break;
				case 'phoneno':
					var reg = /^1[0-9]{10,10}$/;
					if (!reg.test(data[rule[i].name])) { this.error[rule[i].name] = rule[i].errorMsg; result = false; } else { this.error[rule[i].name] = ''; }
				break;
				case 'confirmPassword':
					// confirm password 确认密码 得把第一次的密码给checkRule
					if (data[rule[i].name] !== rule[i].checkRule) { this.error[rule[i].name] = rule[i].errorMsg; result = false; } else { this.error[rule[i].name] = ''; }
				break;
			}
		}
		return result;
	},
	isNumber : function (checkVal){
		var reg = /^-?[1-9][0-9]?.?[0-9]*$/;
		return reg.test(checkVal);
	}
}
// 这里的校验方法是在 hcoder深海 前辈的表单验证方法基础上对我需要用到的场景下修改的

二、引入并使用它

var graceChecker = require("common/graceChecker.js")

data() {
	return {
			customizeCRule: [{
					name: "password",
					checkType: "reg",
					checkRule: "^.{1,5}$",
					errorMsg: "密码应为1-5个字符"
				},
				{
					name: "password2",
					checkType: "confirmPassword",
					checkRule: "",
					errorMsg: "两次输入密码不相同"
				},
				{
					name: "smsCode",
					checkType: "string",
					checkRule: "4,6",
					errorMsg: "验证码应为4-6个字符"
				}
			]
		}
	},

submitSave(e) {
	var formData = e.detail.value
	var checkRes = graceChecker.default.check(formData, this.customizeCRule)
	if (checkRes) {
		console.log('校验通过1')
	} else {
		console.log('校验失败')
		this.errorHandling() // 给失败的项分别加上提示
	}
}

三、精简代码和添加报错提示

由于众多小程序不允许直接操作dom,并且vue的refs只对自定义组件有效,
对uniapp中的标签不生效。内置组件指的是view这些,这个坑是由于这些组件不是vue组件,
且和用户的代码不在同一个环境中(不在逻辑层而在视图层),获取不到。
因此需要自定义组件把报错提示挂上去(如果可以操作dom就省去了这一步)

自定义组件checkTip.vue
<template>
	<view class="content-tip">
		<!-- 自定义组件然后挂载ref操作dom -->
		<view class="check-tip">{{titleText}}</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				titleText: ''
			}
		},
		name: 'CheckTip'
	}
</script>

<style lang="scss">
	.content-tip {
		position: relative;
		.check-tip {
			position: absolute;
			left: 1rpx;
			top: 18rpx;
			width: 600rpx;
			color: #E34343;
			font-size: 24rpx;
		}
	}
</style>

把上面的自定义组件挂载到全局就可以比较方便的在页面中使用它了,main.js中:
import checkTip from 'pages/components/checkTip.vue'
Vue.component('check-tip',checkTip)

现在可以在需要添加校验提示的项上加它:
<view class="cu-form-group">
    <check-tip ref="password" />
	<input placeholder="请输入新密码" name="password" @input="checkChange($event.target.value, 'password')"></input>
</view>
注意:它的ref值应等于该项的name值 便于校验之后它的校验提示找到它
这里添加@input="checkChange()"是为了输入校验


--------------------------------------------------------------
为了精简代码,抽出公共的方法和值:
在mixins文件夹中新建需要混入的js文件:customizeCRule.js

/**
*  自定义验证规则相关
*  校验:1加入check-tip(绑上与name相同的ref值) 2操作dom给tip 3给改变事件(值变化时移除校验结果) 
*  注意:data中务必添加自定义规则customizeCRule
*  报错:Cannot set property 'titleText' of undefined  是因为没给ref 
* @param {String} e 变化的值
* @param {String} key rule的name
* @param {Boolean} customizeCResult 总的校验结果在此处返回,注意:输入校验会将它置未false因此在总校验之前将它置为true吧靓仔
*/

var graceChecker = require("common/graceChecker.js")
export default {
  data() {
    return {
		customizeCResult: true
    }
  },
  methods: {
	errorHandling() {
		var error = graceChecker.default.error
		for(var key in error) {
			console.log(error[key]);
			if(error[key]) {
				this.$refs[key].titleText = error[key]
			}
		}
		uni.showToast({
			title: '校验出错',
			icon: "none"
		})
	},
    checkChange(e, key) {
    	const formData = {}
    	formData[key] = e
    	// this.customizeCRule需要在用到校验的每个页面上定义
    	const rule = this.customizeCRule.filter((i, index) => {
    		if(i.name === key) {
    			return true
    		} else {
    			return false
    		}
    	})
    	var checkRes = graceChecker.default.check(formData, rule)
    	var error = graceChecker.default.error
    	checkRes
    	? this.$refs[key].titleText = ''
    	: (
			this.$refs[key].titleText = error[key],
			this.customizeCResult = false
		)
    },
  }
}


四、完结撒花

最后咱们把代码混入进需要使用到校验的页面:
import customizeCRule from '../mixins/customizeCRule.js'
mixins: [customizeCRule],

补充一下:
可能会有需求是仅校验表单其中两三项的数据,这时候就用到了customizeCRule中的customizeCResult了

getSms2() {
	this.customizeCResult = true // 初始置true 否则重新输入的时候会置false(一次false后续都false)
		this.checkChange(this.form.smsCode, 'smsCode')
		this.checkChange(this.form.mobile2, 'mobile2')
		if(!this.customizeCResult) {
			this.customizeCResult = true
			return
		}
	}

最后给份demo吧

<form @submit="submitSave">
		<view class="cu-form-group">
			<check-tip ref="smsCode" />
			<view class="title">验证码</view>
			<input placeholder="请输入内容" name="smsCode" v-model="form.smsCode" @input="checkChange($event.target.value, 'smsCode')"></input>
			<button :class="smsFlag ? 'cu-btn line-blue bg-disabled bg-sms' : 'cu-btn bg-grey bg-sms'" @click="getSms" :disabled="smsFlag">
				{{smsFlag ? '(' + sixty + ') 秒' : '获取验证码'}}
			</button>
		</view>
		<view class="cu-form-group">
			<check-tip ref="mobile2" />
			<view class="title">新手机号</view>
			<input placeholder="请输入内容" name="mobile2" v-model="form.mobile2" @input="checkChange($event.target.value, 'mobile2')"></input>
		</view>
		<view class="cu-form-group">
			<check-tip ref="smsCode2" />
			<view class="title">验证码</view>
			<input placeholder="请输入内容" name="smsCode2" v-model="form.smsCode2" @input="checkChange($event.target.value, 'smsCode2')"></input>
			<button :class="smsFlag2 ? 'cu-btn line-blue bg-disabled bg-sms' : 'cu-btn bg-grey bg-sms'" @click="getSms2" :disabled="smsFlag2">
				{{smsFlag2 ? '(' + sixty2 + ') 秒' : '获取验证码'}}
			</button>
		</view>
		
		<view class="uni-btn-v">
			<button class="cu-btn bg-grey lg bg-c bottom-button" form-type="submit">保存</button>
		</view>
	</form>

<script>
	import customizeCRule from '../mixins/customizeCRule.js'
	var graceChecker = require("common/graceChecker.js")
	export default {
		mixins: [customizeCRule],
		data() {
			return {
				customizeCRule: [{
						name: "smsCode",
						checkType: "string",
						checkRule: "4,6",
						errorMsg: "验证码应为4-6个字符"
					},
					{
						name: "smsCode2",
						checkType: "string",
						checkRule: "4,6",
						errorMsg: "验证码应为4-6个字符"
					},
					{
						name: "mobile2",
						checkType: "phoneno",
						errorMsg: "不符合电话号码格式"
					}
				],
				......
		methods: {
			submitSave(e) {
				var formData = e.detail.value
				var checkRes = graceChecker.default.check(formData, this.customizeCRule)
				if (checkRes) {
					console.log('校验通过')
				} else {
					console.log('校验失败')
					this.errorHandling()
				}
			}
			......
</script>

Tips:

篇幅有限,graceChecker.js中的校验类型只给出了几种,需要更多校验类型的伙伴们可以自定义一些正则,或者评论留言我加上它们
(最后小声吐槽一下colorUI,纯css的UI库用起来需要自己的逻辑太多了,表单校验也没全,文档巨简陋。不过样式是真好看)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值