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

期望输出

[

{

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

// 是否在可操作列表中

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;

}

},

绑定事件

/**

  • 为DOM添加事件

  • @param {HTMLElement} el 绑定事件的DOM

  • @param {Object} binding 集合

*/

function handleFilter(el, binding) {

switch (binding.arg) {

case “number”:

numberFilter(el);

break;

case “letter”:

letterFilter(el);

break;

break;

default:

codeFilter(el);

break;

}

}

/**

  • 数字验证

  • @param {HTMLElement} el 待绑定元素

*/

const numberFilter = function(el) {

exAddListener(el, () => {

el.value = handleNumber(el.value);

});

};

const addListener = function(el, type, fn) {

el.removeEventListener(type, fn, false);

el.addEventListener(type, fn, false);

};

const exAddListener = function(el, fn) {

addListener(el, “compositionstart”, (e) => {

e.target.isNeedPrevent = true;

});

addListener(el, “compositionend”, (e) => {

e.target.isNeedPrevent = false;

});

addListener(el, “keydown”, (e) => {

e.target.keyEvent = true;

});

addListener(el, “keyup”, (e) => {

if (e.target.isNeedPrevent) return;

fn();

e.target.keyEvent = false;

});

};

/**

  • 字母验证

  • @param {HTMLElement} el 待绑定元素

*/

const letterFilter = function(el) {

exAddListener(el, () => {

el.value = el.value.replace(/[^A-Za-z]+/g, “”);

});

};

不知有没有小伙伴发现,这里绑定的事件是keyup而不是Input,可能有小伙伴认为绑定input更为合理,这个也是我一开始的疑问,后来经过确认,是因为这样:input会直接在输入的时候有一个校验,它最终实现的效果会导致input里直接无法输入不合法的内容,如果这样,那么用户可能会有“是不是我键盘坏了?”之类的疑问,但是如果是keyup事件,那么此时会有一个时间差,输入时确实输入了内容,只是松开键盘时又将输入的内容删除了,这样用户会有一个交互上的反馈,这将隐性的提示用户输入不合法;想想还挺有道理…

小结

通过自定义指令的方式,可以非常便捷的帮助开发人员做校验的验证,用法也非常的简单,我个人觉得这是一个非常可行的技术方案,要说它最大的问题,无非就是无法有效的利用IView或ElementUI的错误提示,只要能解决这个问题,其实是非常优秀的用法;

最后

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

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

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

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

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

[外链图片转存中…(img-WSXitGgp-1715721591857)]

[外链图片转存中…(img-XUAWgzxG-1715721591857)]

[外链图片转存中…(img-qB7Ck5Tq-1715721591858)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

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

  • 27
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对表格字段进行输入校验可以通过以下步骤实现: 1. 在表格将要进行校验的字段设置为可编辑的输入框,并绑定一个 v-model 指令,用于实时获取输入框的值。 2. 在需要校验的时候,通过正则表达式或其他方式校验输入框的值是否符合要求。 3. 如果输入框的值不符合要求,可以通过弹窗、提示框等方式提示用户输入不合法,并将输入框的值重置为之前的值,或者让用户重新输入。 以下是一个简单的示例代码,以手机号码为例进行校验: ``` <template> <div> <table> <thead> <tr> <th>姓名</th> <th>手机号码</th> </tr> </thead> <tbody> <tr v-for="(item, index) in list" :key="index"> <td>{{ item.name }}</td> <td> <input type="text" v-model="item.phone" @blur="checkPhone(item)" /> </td> </tr> </tbody> </table> </div> </template> <script> export default { data() { return { list: [ { name: '张三', phone: '13888888888' }, { name: '李四', phone: '13999999999' }, { name: '王五', phone: '13000000000' } ] } }, methods: { checkPhone(item) { const reg = /^1[3-9]\d{9}$/ // 手机号码正则表达式 if (!reg.test(item.phone)) { alert('请输入正确的手机号码') item.phone = '' // 重置输入框的值 } } } } </script> ``` 在上面的示例代码,通过在输入框上绑定 @blur 事件,在输入框失去焦点时触发校验手机号码的方法 checkPhone。如果手机号码不符合要求,弹出提示框,并重置输入框的值。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值