《Vue》聊一聊实际项目中输入框的校验的几种优化方案

formValidate: {

name: ‘’,

mail: ‘’,

},

ruleValidate: {

name: [

{ required: true, message: ‘The name cannot be empty’, trigger: ‘blur’ }

],

mail: [

{ required: true, message: ‘Mailbox cannot be empty’, trigger: ‘blur’ },

{ type: ‘email’, message: ‘Incorrect email format’, trigger: ‘blur’ }

]

}

}

}

}

这是官网的例子,裁剪了一部分代码,原版代码太多了,在这次查看的项目中同样发现了大量这种较为基础的用法,这种用法对对于需要在一个界面上放十几个输入框的设计,会存在大量重复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’ }

]

)

有的小伙伴可能会说,这不行啊这使用场景太局限了,就只能验证必输项,太鸡肋…到这里仅仅是抛砖引玉,只是提供了个思路,在实用性上还是有很大缺陷的,如果有小伙伴希望能具体细聊一下,那我们就简单说下,一般常规的验证规则大致可以分为以下几种:

  1. 仅必输项,无其他验证规则;

  2. 仅允许英文字母;

  3. 仅允许数字;

  4. 仅允许英文字母和数字;

那我们就预设几个参数,分别对应:提示信息,是否必输,验证方式,大致运行流程如下:

流程图

在这里插入图片描述

效果

经过转换后,效果依旧是原来的效果,并没有影响其正常使用,错误提示依然是借助于IView或者ElementUI的错误提示实现

在这里插入图片描述

期望结果

期望输入

handleParams({messgage:“用户名不能为空”},“code”)

期望输出

[

{

required: true,

message: “用户名不能为空”,

trigger: “blur”,

},

{

// validate:根据参数实现的自定义校验

validator: validate(isCode, “请输入数字或字母”),

trigger: “blur”,

}

]

实现

  1. 第一步就是对参数的初始化,在这一步中,我们需要对参数进行简略的处理,并且定义一个默认参数,大致如下代码;

// 将参数转成数组,方便处理

const args = [].slice.call(arguments);

// 默认配置

const DEFAULT_MESSAGE = {

required: true,

message: “该输入项为必填项”,

trigger: “blur”,

};

  1. 处理参数,根据具体的参数的转成对应的合法参数并返回,这里需要对输入做一个合法性进行判断;

// 处理参数

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;

};

  1. 生成对应类型的自定义校验规则;

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;

}

}

小结

简单的来说就是实现差不多就是这样,可能有不完善的地方,但大致方向没有问题,之后便是扩展了,扩展的话需要根据自身的需求进行进一步可扩展了;

回过头来想我们抽离的最终目的,最终我们的目的就是为了实现:

  1. 减少书写的代码量,过于频繁的书写校验规则和必输这些数组实在浪费时间;

  2. 统一管理校验代码,尤其是协同开发的时候,一个人在某个业务场景里写了一遍自定义校验了,如果另外一个在不知道的情况下也同样写了一遍,那是不是浪费时间;

  3. 减少BUG提升开发效率,不可否认的是在一个项目组中,尤其是规模不大的小项目组,并不是每个人都能书写公共方法,很多新人往往考虑不周导致了隐性BUG的存在,如果一开始就有人将工具函数写完整,那么开发效率和BUG可以避免很多

方式二:自定义指令


这种方式其实有点 另类 ,也是我们某个项目中用到的,不是特别正统,但是发展方向我觉得还是没有问题的,它最终实现的效果是, 让输入框只能输入我们期望的合法值,如果输入值不合法,直接会被删除无法输入;这也就导致了它并不能 有效的利用IView或者ElementUI的错误提示,这也就是我为什么说它有点另类的原因;

虽然它没有有效的利用formItem的错误提示,但在体验上影响却不大,必输这一块它依然使用的是async-validator,再加之用法简单,确实有些独到之处;

效果

大致效果如下,是不是相较于正常的错误提示,这种稍微有那么一点点另类…

在这里插入图片描述

用法

// 以IView的Input组件为例

大致用法就这么简单,当输入的内容不为数字时,直接将该字符串给delete掉,这样就达到了控制输入的目的;

流程图

在这里插入图片描述

实现

其实没有太多的技术难点,总结一下,主要的技术点在于以下几个:

  1. 获取DOM,因为绑定的DOM必须是input或者包含input,而不管是IView还是ElementUI的Input组件都不是单纯的Input,是div以及Input的组合,毕竟涉及到了样式问题,因此第一步需要对绑定DOM的获取与判定;

  2. 输入时中文输入的异常处理,当正在输入中文的时候,输入框内会存在重复触发的问题,但这个可以通过compositionstartcompositionend解决;

解决了这两个问题,大致代码如下:

获取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();

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

最后

文章到这里就结束了,如果觉得对你有帮助可以点个赞哦,如果有需要前端校招面试题PDF完整版的朋友可以点击这里即可获取,包括答案解析。

开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**

[外链图片转存中…(img-d08voFNE-1712553589828)]

[外链图片转存中…(img-F6Xr8dES-1712553589828)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

[外链图片转存中…(img-Z3kT31f1-1712553589829)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

最后

文章到这里就结束了,如果觉得对你有帮助可以点个赞哦,如果有需要前端校招面试题PDF完整版的朋友可以点击这里即可获取,包括答案解析。

[外链图片转存中…(img-Jnj7Si7v-1712553589829)]

  • 26
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值