我们项目中的UI框架基本都是使用的IView,其实包括ElemenUI在内的这两者的表单验证都是使用的async-validator,先看一下IView官网的例子,
这是官网的例子,裁剪了一部分代码,原版代码太多了,在这次查看的项目中同样发现了大量这种较为基础的用法,这种用法对对于需要在一个界面上放十几个输入框的设计,会存在大量重复rules代码,并且重复的量还特别太夸张,比如,我增见到过一个弹窗,光是输入框就将近15个,写了光是这个ruleValidate就写了100多行…直呼牛皮…
可能有很多小伙伴发现,这种写法中除了message提示的信息不一样,其它配置都是完全一致的,从共性抽离的角度来讲,那不是完全可以抽离?
============================================================
既然是优化,那么首先需要确认的就是可优化点,正如上面所说,经过分析发现,大量输入框的校验只有一种,必输项,换个说法就是这个输入框必须输入,除此之外没有别的限制,但是仅仅这一个需求,最后可能演变的代码就变成了这样:
ruleValidate: {
name: [
{ required: true, message: ‘The name cannot be empty’, trigger: ‘blur’ }
],
mail: [
{ required: true, message: ‘Mailbox cannot be empty’, trigger: ‘blur’ }
],
city: [
{ required: true, message: ‘Please select the city’, trigger: ‘blur’ }
],
gender: [
{ required: true, message: ‘Please select gender’, trigger: ‘blur’ }
],
desc: [
{ required: true, message: ‘Please enter a personal introduction’, trigger: ‘blur’ }
]
}
其实完全没有必要,不同数组之间最大的区别也就是提示的文字不同,我们完全可以抽离一个公共函数来做统一处理,比如,我们期望改完后关于验证是这么写的:
ruleValidate: {
name: Validate(“The name cannot be empty”),
mail: Validate(“Mailbox cannot be empty”),
city: Validate(“Please select the city”),
gender: Validate(“Please select gender”),
desc: Validate(“Please enter a personal introduction”)
}
这不比每一次校验输入一个数组,每一次都要写一遍来的轻松,而且实现也并不复杂,最简单的如下:
function Validate(msg)(
return [
{ required: true, message: msg, trigger: ‘blur’ }
]
)
有的小伙伴可能会说,这不行啊这使用场景太局限了,就只能验证必输项,太鸡肋…到这里仅仅是抛砖引玉,只是提供了个思路,在实用性上还是有很大缺陷的,如果有小伙伴希望能具体细聊一下,那我们就简单说下,一般常规的验证规则大致可以分为以下几种:
-
仅必输项,无其他验证规则;
-
仅允许英文字母;
-
仅允许数字;
-
仅允许英文字母和数字;
那我们就预设几个参数,分别对应:提示信息,是否必输,验证方式,大致运行流程如下:
流程图
效果
经过转换后,效果依旧是原来的效果,并没有影响其正常使用,错误提示依然是借助于IView或者ElementUI的错误提示实现
期望结果
期望输入
handleParams({messgage:“用户名不能为空”},“code”)
期望输出
[
{
required: true,
message: “用户名不能为空”,
trigger: “blur”,
},
{
// validate:根据参数实现的自定义校验
validator: validate(isCode, “请输入数字或字母”),
trigger: “blur”,
}
]
实现
- 第一步就是对参数的初始化,在这一步中,我们需要对参数进行简略的处理,并且定义一个默认参数,大致如下代码;
// 将参数转成数组,方便处理
const args = [].slice.call(arguments);
// 默认配置
const DEFAULT_MESSAGE = {
required: true,
message: “该输入项为必填项”,
trigger: “blur”,
};
- 处理参数,根据具体的参数的转成对应的合法参数并返回,这里需要对输入做一个合法性进行判断;
// 处理参数
const params = handleParams(args);
/**
-
处理参数
-
@param {Array} array 参数
-
@returns 合法值
*/
const handleParams = (array) => {
const result = {
type: “”,
require: null,
};
if (array.length === 0) {
result.require = DEFAULT_MESSAGE;
} else {
for (let item = 0; item < 2; item++) {
if (utils.isString(array[item])) {
result.type = array[item];
} else if (utils.isObj(array[item])) {
result.require = array[item];
// 判断用户是否手写了require,默认true
result.require.required = utils.hasProperty(
array[item],
“required”
)
-
? array[item].required
- true;
}
}
if (result.require === null) {
result.require = DEFAULT_MESSAGE;
}
}
return result;
};
- 生成对应类型的自定义校验规则;
if (params.type !== “”) {
switch (params.type) {
case “code”:
rules.push({
validator: validate(isCode, “请输入数字或字母”),
trigger: “blur,change”,
});
break;
case “mobile”:
rules.push({
validator: validate(isMobile, “请输入正确的手机号”),
trigger: “blur,change”,
});
break;
case “number”:
rules.push({
validator: validate(isNumber, “请输入数字”),
trigger: “blur,change”,
});
break;
case “letter”:
rules.push({
validator: validate(isLetter, “请输入字母”),
trigger: “blur,change”,
});
break;
default:
rules.push({});
break;
}
}
小结
简单的来说就是实现差不多就是这样,可能有不完善的地方,但大致方向没有问题,之后便是扩展了,扩展的话需要根据自身的需求进行进一步可扩展了;
回过头来想我们抽离的最终目的,最终我们的目的就是为了实现:
-
减少书写的代码量,过于频繁的书写校验规则和必输这些数组实在浪费时间;
-
统一管理校验代码,尤其是协同开发的时候,一个人在某个业务场景里写了一遍自定义校验了,如果另外一个在不知道的情况下也同样写了一遍,那是不是浪费时间;
-
减少BUG提升开发效率,不可否认的是在一个项目组中,尤其是规模不大的小项目组,并不是每个人都能书写公共方法,很多新人往往考虑不周导致了隐性BUG的存在,如果一开始就有人将工具函数写完整,那么开发效率和BUG可以避免很多
这种方式其实有点 另类 ,也是我们某个项目中用到的,不是特别正统,但是发展方向我觉得还是没有问题的,它最终实现的效果是, 让输入框只能输入我们期望的合法值,如果输入值不合法,直接会被删除无法输入;这也就导致了它并不能 有效的利用IView或者ElementUI的错误提示,这也就是我为什么说它有点另类的原因;
虽然它没有有效的利用formItem的错误提示,但在体验上影响却不大,必输这一块它依然使用的是async-validator,再加之用法简单,确实有些独到之处;
效果
大致效果如下,是不是相较于正常的错误提示,这种稍微有那么一点点另类…
用法
// 以IView的Input组件为例
大致用法就这么简单,当输入的内容不为数字时,直接将该字符串给delete掉,这样就达到了控制输入的目的;
流程图
实现
其实没有太多的技术难点,总结一下,主要的技术点在于以下几个:
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)
最后
本人分享一下这次字节跳动、美团、头条等大厂的面试真题涉及到的知识点,以及我个人的学习方法、学习路线等,当然也整理了一些学习文档资料出来是附赠给大家的。知识点涉及比较全面,包括但不限于前端基础,HTML,CSS,JavaScript,Vue,ES6,HTTP,浏览器,算法等等
详细大厂面试题答案、学习笔记、学习视频等资料领取,点击资料领取直通车
前端视频资料:
hTZ8KQS-1712994183940)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
[外链图片转存中…(img-GaAGOzer-1712994183940)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)
最后
本人分享一下这次字节跳动、美团、头条等大厂的面试真题涉及到的知识点,以及我个人的学习方法、学习路线等,当然也整理了一些学习文档资料出来是附赠给大家的。知识点涉及比较全面,包括但不限于前端基础,HTML,CSS,JavaScript,Vue,ES6,HTTP,浏览器,算法等等
详细大厂面试题答案、学习笔记、学习视频等资料领取,点击资料领取直通车
[外链图片转存中…(img-UkjRAkut-1712994183941)]
前端视频资料: