使用策略模式优化表单校验
最近一直在做一些涉及到表单校验的业务
假设现在我要写一个注册页面,在店家注册按钮之前,有如下几条校验逻辑:
- 用户名不能为空
- 密码长度不能小于6位
- 手机号码必须符合格式
最粗暴的校验方式
缺点:
- 扩展性如此的差。
- 刚接手项目的人甚至是写代码的本人在添加别的校验需求时无从下手。
- 如果增加一条新的校验规则,或者想把免得长度校验从6位增加到8位,要去registerForm.onsubmit内部更改,这样就违反了开放-封闭的原则。
registerForm.onsubmit = function () {
if (username != "") {
if (password.length >= 6) {
if (/^1[3|4|5|7|8][0-9]{9}$/.test(tel)) {
alert('成功');
} else {
alert('请输入正确的的手机号!');
return false;
}
} else {
alert('密码不能小于六位');
return false;
}
} else {
alert("用户名不能为空!");
return false;
}
}
使用策略模式来优化表单校验
第一步我们先来把这些校验逻辑封装成策略对象
// 名字存在 密码长度不能少于6位 手机格式不正确
let rules = {
// errorMsg参数,提升了适用性
isNonEmpty: function (value, errorMsg) { //不为空
if (value === '') {
// 返回字符串true 错误信息
return errorMsg;
}
},
minLength: function (value, length, errorMsg) { //限制最小长度
if (value.length < length) {
return errorMsg;
}
},
isMobile: function (value, errorMsg) {
if (!/^1[1|5|8|7|4|3][0-9]{9}$/.test(value)) { //电话号码校验
return errorMsg;
}
}
}
接下来就是实现Validator类了。
- 声明一个缓存cache存储规则便于后续一次性校验
- 添加规则,解析规则并push至cache中
- 一次性执行校验
class Validator {
constructor() {
this.cache = []
}
add(ele, rule, errMsg) {
const arr = rule.split(':')
this.cache.push(function () {
let r = arr.shift()
arr.unshift(ele.value)
arr.push(errMsg)
return rules[r].apply(ele, arr)
})
}
start() {
for (var i = 0, validatorFunc; validatorFunc = this.cache[i++];) {
var msg = validatorFunc();
if (msg) {
return msg;
}
}
}
}
进行校验
function validateFunc() {
// 校验处理 分离出去
var validator = new Validator(); //创建validator对象
// 一个个去校验
// 数组 遍历
/**********************添加校验规则**********************/
validator.add(username, 'isNonEmpty', '用户名不能为空');
validator.add(password, 'minLength:6', '密码长度不能少于6位');
validator.add(tel, 'isMobile', '手机号码格式不正确')
var errorMsg = validator.start(); //获取校验结果
// 一个个去校验
return errorMsg; //返回校验结果
}
registerForm.onsubmit = function () {
// 一票规则 数组
var errorMsg = validateFunc(); //如果errorMsg有确切的返回值,说明校验未通过,即输入的内容不符合规则
if (errorMsg) {
alert(errorMsg);
return false; //阻止表单提交
}
}