工作中,我们经常会遇到表单信息提交时,需要校验表单格式,拦截无效请求,此时不可避免的就是用大量的if return
去拦截。还要重复写大量的errorMessage
,如下场景:
// 下面是业务场景的字段及格式要求
userName:必填,
phone: 必填,正则验证,已设置max = 11
address:至少两位,已设置max = 150
一般的代码逻辑校验会这么写:
// formData
const {
userName,
phone,
address = ''
} = formData;
if (!userName) {
showErrorMsg('userName is required');
return;
}
if (!phone) {
showErrorMsg('phone is required');
return;
}
const reg = /^1[3456789]\d{9}$/;
if (!reg.test(phone)) {
showErrorMsg('Please check the phone in the correct format');
return;
}
if (address.length < 2) {
showErrorMsg('address needs two words at least');
return;
}
// 如果还有其他相同的字段格式,还是要写if...
// post formdata...
有大量的if return
和showErrorMsg
显得不是很优雅,并且如果遇到不同字段的相同的格式要求(譬如userName和phone都是必填项,但写了两次if
)那能不能只写一次呢?根据场景,只要一个字段校验不通过就可以return了,那就可以通过forEach
+ try catch
的方式进行捕获错误信息,如下:
// formData
const {
userName,
phone,
address = ''
} = formData;
let isCheck = true;
// 填写错误规则
const rules = {
userName: {
required: 'userName is required',
},
phone: {
required: 'phone is required',
regex: {
reg: /^1[3456789]\d{9}$/,
msg: 'Please check the phone in the correct format'
}
},
address: {
min: {
limit: 2,
msg: 'address needs two words at least'
}
}
};
// forEach 校验
try {
Object.keys(formData).forEach(item => {
const ruleItem = rules[item];
if (!ruleItem) {
return;
}
const formItem = formData[item];
if (ruleItem.required && !formItem) {
throw ruleItem.required;
}
if (ruleItem.regex && !regex.reg.test(formItem)) {
throw ruleItem.regex.msg;
}
if (ruleItem.min && formItem < ruleItem.min.limit) {
throw ruleItem.min.msg;
}
// ..其他规则,所有的规则只需要写一次
})
} catch (err) {
isCheck = false;
showErrorMsg(err);
// 校验结果,视情景需要
// return isCheck;
return;
}
// post formData...
代码经过了上面的处理,所有的规则只需要写一次即可判断,这样就可以单独将校验函数抽出来进行封装,只需开发者传入校验规则和校验的数据就可以得到校验结果返回true or false
了。这样是不是更加方便优雅了呢。
同样的也有一个弊端,这样的写法也对格式要求比较严格,期待大家留言给我更好的想法。