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掉,这样就达到了控制输入的目的;
流程图
实现
其实没有太多的技术难点,总结一下,主要的技术点在于以下几个:
-
获取DOM,因为绑定的DOM必须是input或者包含input,而不管是IView还是ElementUI的Input组件都不是单纯的Input,是div以及Input的组合,毕竟涉及到了样式问题,因此第一步需要对绑定DOM的获取与判定;
-
输入时中文输入的异常处理,当正在输入中文的时候,输入框内会存在重复触发的问题,但这个可以通过compositionstart和compositionend解决;
解决了这两个问题,大致代码如下:
获取DOM
getElement(el, type) {
// 容错判断,排除非DOM
if (!(el instanceof HTMLElement)) {
console.error(“类型错误,绑定对象必须是HTMLElement”);
return false;
}
const list = type === “input” ? INPUT : DISABLED_LIST;
const domTagName = el.tagName.toLowerCase();
// 是否在可操作列表中
if (list.indexOf(domTagName) > -1) {
return el.getAttribute(“type”) === null ||
el.getAttribute(“type”) === “text”
-
? el
- false;
}
// 子集是否存在可操作列表中的元素
else {
const domList = [].slice.call(el.querySelectorAll(list.join(“,”)));
if (domList.length === 0) return false;
// 遍历子集
for (let item = 0; item < domList.length; item++) {
if (
domList[item].getAttribute(“type”) === null ||
domList[item].getAttribute(“type”) === “text”
) {
return domList[item];
}
}
return false;
}
},
绑定事件
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)
最后
给大家分享一些关于HTML的面试题,有需要的朋友可以戳这里获取,先到先得哦。
,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
[外链图片转存中…(img-WsikoTRR-1712553527672)]
[外链图片转存中…(img-urdlzsHb-1712553527673)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
[外链图片转存中…(img-uwWUtGWs-1712553527673)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)
最后
给大家分享一些关于HTML的面试题,有需要的朋友可以戳这里获取,先到先得哦。
[外链图片转存中…(img-RzrtZKEw-1712553527674)]
[外链图片转存中…(img-FHh8D79K-1712553527674)]