持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第9天,点击查看活动详情
开场白
表单验证的姿势,简单的if到各种封装的验证库,数不胜数。众所周知,软件行业没有银弹,能解决问题的方法就是好方案。
很多时候,我们用方案a解决了当前问题,但随着项目迭代,方案a会出现局限性,这时候就需要我们使用方案a+加于修正。这段话主要是用来表明没有一劳永逸的方案,代码正如滴增般,放任自由,只会越来越混沌。
表单验证
项目现在有一个表单详情,必填有标题、封面、介绍文、内容,代码上是一个 if 对应一个必填。需求后面慢慢迭代,又陆续增加了数个必填,if也是陆续补上,代码渐渐产生坏味道。后面又添加了复杂的逻辑关系,某些字段互相关联,这时候再用if去组织的话,整个验证代码过于面向过程,整体结构松散,难以阅读。
代码腐烂是不会自愈的,需要我们重构干扰。是不是要安个验证库来重构?但是我不想过多浪费时间去学习这个验证库,我想要更加简单的形似去处理。这时候我想到了Object
// 定义一个object,key是提示语,value是布尔值
const verificationData = {
'请输入xxx': !data
}
// 如果参数verificationData的value有为true的话,则返回对应的key
const text = formValidation(verificationData)
if (text) {
this.$message(text)
return false
}
通过上面的提示语/布尔值的数据结构去组织表单判断,对比if形似,整体结构更加直观,一眼就看到某些表单值对应的提示语,实现formValidation函数,用来遍历verificationData。
有一个缺点,遍历object的时候,key的顺序并不会按我们预设中的object一致,它是有自己的一套顺序遍历。我们需要一个新的数据结构载体,满足提示语/布尔值和预设顺序,数组第一个条件不符合,倒是es6的Map形神兼备
// new一个Map,类似object那种结构
const verificationData new Map([
["请输入xxx", !data],
["请输入xxx", function (){return !data}], // 支持函数,对于复杂的表单验证
)]
const text = formValidation(verificationData)
if (text) {
this.$message(text)
return false
}
// formValidation具体的实现方式
const formValidation = map => {
if (!(map instanceof Map)) throw new Error("请使用Map类型");
for (let [key, value] of map.entries()) {
const b = typeof value === "function" ? value() : value;
if (b) {
return key;
}
}
};