从0开始,编写一个验证函数(工具函数)

32次阅读

共计 6947 个字符,预计需要花费 18 分钟才能阅读完成。

为什么要写验证函数
将验证过程变成多个步骤
完成一个基本的验证函数

1. 为什么要写验证函数之前写项目的时候,一般都是在登录注册,修改密码的时候有需要些正则的需求,所以每次用到的时候都是直接从前面的代码 copy 过去就好了,直到后台开始写后台管理系统类的项目,复制粘贴已经完全不可行了。怎么能做一个只会 ctrl+c,ctrl+ v 的程序猿呢!简直不能忍,于是就想到了自己写一个验证函数,每次需要做验证的时候只需要调用这个函数,传入参数就可以了,想想都美滋滋。

2. 将验证过程变成多个步骤做验证的时候我们要做的,定义验证失败后的提示,编写验证的方法,然后调用验证得到结果。一个验证的过程,一般便是分为这几步。
var validatorObj = {
// 验证定义
validator: {
// 验证失败后的提示
messages: {},
// 验证的方法,返回一个布尔值
methods: {}
},
// 得到验证结果
checkResult: {}
}
先定义一些验证失败的提示:
定义的错误提示可以自定义,至于 {0} {1} 等则是用来做一个标识符,在验证失败后会将要验证的参数替换掉标识符

// 验证失败后的提示
messages: {
notnull: ‘ 请输入{0}’,
max: ‘ 长度最多为 {1} 个字符 ’,
min: ‘ 长度最小为 {1} 个字符 ’,
length: ‘{0}的长度在 {1} 到 {2} 个字符 ’,
number: ‘{0}必须是数字 ’,
string: ‘{0}必须是字母或者数字 ’,
moblie: ‘{0}必须是手机或者电话号码格式 ’,
noChinese: ‘{0}不能为中文 ’,
lon: ‘{0}范围为 -180.0~+180.0(必须输入 1 到 10 位小数)’,
lat: ‘{0}范围为 -90.0~+90.0(必须输入 1 到 10 位小数)’,
url: ‘ 请输入正确的 {0} 访问地址 ’,
repeat: ‘ 两次输入的 {0} 不一致 ’,
email: ‘ 邮箱格式不正确 ’,
password: ‘ 请输入由大小写字母 + 数字组成的 6 -16 位密码 ’,
fixedNum: ‘ 请输入 {1} 位数字 ’
}
在定义对应的验证方法:
可以看到几乎在每个验证前面都加了一个当数据为空的时候,返回为 true,这是因为有的时候我们并不关心某一个数据是否填写,但一旦填写了,又要求符合某种规则。所以如果要验证非空的时候,需要使用两个验证属性。

// 验证的方法,返回一个布尔值
methods: {
notnull: obj => {
return obj.value || obj.value === 0
},
max: obj => {
if (!obj.value) return true
return obj.conditions[0] >= obj.value.length
},
min: obj => {
if (!obj.value) return true
return obj.value.length >= obj.conditions[0]
},
length: obj => {
if (!obj.value) return true
return obj.conditions[0] <= obj.value.length && obj.value.length <= obj.conditions[1]
},
number: obj => {
if (!obj.value) return true
reg = /^[0-9]+.?[0-9]*$/
return reg.test(obj.value)
},
string: obj => {
if (!obj.value) return true
reg = /^[a-zA-Z0-9]+$/
return reg.test(obj.value)
},
moblie: obj => {
if (!obj.value) return true
reg = /^(1[3,5,8,7]{1}[\d]{9})|(((400)-(\d{3})-(\d{4}))|^((\d{7,8})|(\d{4}|\d{3})-(\d{7,8})|(\d{4}|\d{3})-(\d{3,7,8})-(\d{4}|\d{3}|\d{2}|\d{1})|(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1}))$)$/
return reg.test(obj.value)
},
noChinese: obj => {
if (!obj.value) return true
reg = /[\u4e00-\u9fa5]/
return !reg.test(obj.value)
},
lon: obj => {
if (!obj.value) return true
reg = /^[\-\+]?(0?\d{1,2}\.\d{1,5}|1[0-7]?\d{1}\.\d{1,10}|180\.0{1,10})$/
return reg.test(obj.value)
},
lat: obj => {
if (!obj.value) return true
reg = /^[\-\+]?([0-8]?\d{1}\.\d{1,10}|90\.0{1,10})$/
return reg.test(obj.value)
},
url: obj => {
if (!obj.value) return true
reg = /^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/)(([A-Za-z0-9-~]+)\.)+([A-Za-z0-9-~\/])+$/
return reg.test(obj.value)
},
repeat: obj => {
if (!obj.value) return true
return obj.value === obj.value1
},
email: obj => {
if (!obj.value) return true
reg = /^([-_A-Za-z0-9\.]+)@([_A-Za-z0-9]+\.)+[A-Za-z0-9]{2,3}$/
return reg.test(obj.value)
},
password: obj => {
if (!obj.value) return true
reg = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z\d]{6,16}$/
return reg.test(obj.value)
},
fixedNum: obj => {
if (!obj.value) return true
return obj.value.length === obj.conditions[0]
}
}
调用验证方法:
这里是调用验证函数的方法,和上面的定义结合起来。
传入要验证的规则,验证的值,验证的字段名字,如果有条件则加上条件数组

/**
1. 传入验证规则,得到验证结果
2. @param {Obj} {label, value, rules, conditions}
3. @param {String} label: 验证的字段名称
4. @param {String} value: 验证的值 (验证重复的时候可以添加 value1 属性)
5. @param {Array} rules: 验证的规则数组 例如:[‘notnull’, ‘length’] 如果参数必填,第一个参数为 notnull
6. @param {Array} conditions: 条件字段 例如:[‘2′, ’10’] , 则验证长度错误会提示: 密码的长度在 2 到 10 个字符, 以传入数组的条件去做验证, 验证的提示 {1} 开始将匹配的是当前数组
7. @return {obj} {result, message} 验证结果对象
*/
// 得到验证结果
checkResult: function (obj) {
let result = true,
checkType,
message = ‘ 验证成功 ’,
validatorMethods = this.validator.methods,
validatorMessage = this.validator.messages
// 循环验证
for (let i = 0, len = obj.rules.length; i < len; i++) {
// 得到当前验证失败信息
if (!validatorMethods[obj.rules[i]](obj)) {
checkType = obj.rules[i]
result = false
break
}
}
// 如果验证失败, 得到验证失败的结果集
if (!result) {
message = validatorMessage[checkType]
if (obj.conditions) {
obj.conditions.forEach((item, index) => {
message = message.replace(‘{‘ + (index + 1) + ‘}’, item)
})
}
message = message.replace(‘{0}’, obj.label)
return {result, message}
}

return {result, message}
}
3. 完整的验证函数把上面的步骤拼在一起,就可以完成一个验证函数。具体的需求和使用,可以根据项目自定义,但思路大致是这样的。
使用示例: validate({label: ‘username’, value: ‘admin’, rules: [‘notnull’, ‘length’], conditions: [‘2′, ’10’]}) // 验证 username 不为空且长度在 2 -10 之间
validate({label: ‘pawwword’, value: ‘lllyh111’, rules: [‘notnull’, ‘password’]}) // 验证 password 由大小写字母 + 数字组成的 6 -16 位密码

验证返回结果: {result: true, message: ‘ 验证成功 ’}
{result: false, message: ‘ 验证失败提示 ’}

/**
* 传入验证规则,得到验证结果
* @param {Obj} {label, value, rules, conditions}
* @param {String} label: 验证的字段名称
* @param {String} value: 验证的值 (验证重复的时候可以添加 value1 属性)
* @param {Array} rules: 验证的规则数组 例如:[‘notnull’, ‘length’] 如果参数必填,第一个参数为 notnull
* @param {Array} conditions: 条件字段 例如:[‘2′, ’10’] , 则验证长度错误会提示: 密码的长度在 2 到 10 个字符, 以传入数组的条件去做验证, 验证的提示 {1} 开始将匹配的是当前数组
* @return {obj} {result, message} 验证结果对象
*/
function validate (obj) {
let reg
const validatorObj = {
// 验证定义
validator: {
// 验证失败后的提示
messages: {
notnull: ‘ 请输入{0}’,
max: ‘ 长度最多为 {1} 个字符 ’,
min: ‘ 长度最小为 {1} 个字符 ’,
length: ‘{0}的长度在 {1} 到 {2} 个字符 ’,
number: ‘{0}必须是数字 ’,
string: ‘{0}必须是字母或者数字 ’,
moblie: ‘{0}必须是手机或者电话号码格式 ’,
noChinese: ‘{0}不能为中文 ’,
lon: ‘{0}范围为 -180.0~+180.0(必须输入 1 到 10 位小数)’,
lat: ‘{0}范围为 -90.0~+90.0(必须输入 1 到 10 位小数)’,
url: ‘ 请输入正确的 {0} 访问地址 ’,
repeat: ‘ 两次输入的 {0} 不一致 ’,
email: ‘ 邮箱格式不正确 ’,
password: ‘ 请输入由大小写字母 + 数字组成的 6 -16 位密码 ’,
fixedNum: ‘ 请输入 {1} 位数字 ’
},
// 验证的方法, 返回一个布尔值
methods: {
notnull: obj => {
return obj.value || obj.value === 0
},
max: obj => {
if (!obj.value) return true
return obj.conditions[0] >= obj.value.length
},
min: obj => {
if (!obj.value) return true
return obj.value.length >= obj.conditions[0]
},
length: obj => {
if (!obj.value) return true
return obj.conditions[0] <= obj.value.length && obj.value.length <= obj.conditions[1]
},
number: obj => {
if (!obj.value) return true
reg = /^[0-9]+.?[0-9]*$/
return reg.test(obj.value)
},
string: obj => {
if (!obj.value) return true
reg = /^[a-zA-Z0-9]+$/
return reg.test(obj.value)
},
moblie: obj => {
if (!obj.value) return true
reg = /^(1[3,5,8,7]{1}[\d]{9})|(((400)-(\d{3})-(\d{4}))|^((\d{7,8})|(\d{4}|\d{3})-(\d{7,8})|(\d{4}|\d{3})-(\d{3,7,8})-(\d{4}|\d{3}|\d{2}|\d{1})|(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1}))$)$/
return reg.test(obj.value)
},
noChinese: obj => {
if (!obj.value) return true
reg = /[\u4e00-\u9fa5]/
return !reg.test(obj.value)
},
lon: obj => {
if (!obj.value) return true
reg = /^[\-\+]?(0?\d{1,2}\.\d{1,5}|1[0-7]?\d{1}\.\d{1,10}|180\.0{1,10})$/
return reg.test(obj.value)
},
lat: obj => {
if (!obj.value) return true
reg = /^[\-\+]?([0-8]?\d{1}\.\d{1,10}|90\.0{1,10})$/
return reg.test(obj.value)
},
url: obj => {
if (!obj.value) return true
reg = /^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/)(([A-Za-z0-9-~]+)\.)+([A-Za-z0-9-~\/])+$/
return reg.test(obj.value)
},
repeat: obj => {
if (!obj.value) return true
return obj.value === obj.value1
},
email: obj => {
if (!obj.value) return true
reg = /^([-_A-Za-z0-9\.]+)@([_A-Za-z0-9]+\.)+[A-Za-z0-9]{2,3}$/
return reg.test(obj.value)
},
password: obj => {
if (!obj.value) return true
reg = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z\d]{6,16}$/
return reg.test(obj.value)
},
fixedNum: obj => {
if (!obj.value) return true
return obj.value.length === obj.conditions[0]
}
}
},
// 得到验证结果
checkResult: function (obj) {
let result = true,
checkType,
message = ‘ 验证成功 ’,
validatorMethods = this.validator.methods,
validatorMessage = this.validator.messages
// 循环验证
for (let i = 0, len = obj.rules.length; i < len; i++) {
// 得到当前验证失败信息
if (!validatorMethods[obj.rules[i]](obj)) {
checkType = obj.rules[i]
result = false
break
}
}
// 如果验证失败, 得到验证失败的结果集
if (!result) {
message = validatorMessage[checkType]
if (obj.conditions) {
obj.conditions.forEach((item, index) => {
message = message.replace(‘{‘ + (index + 1) + ‘}’, item)
})
}
message = message.replace(‘{0}’, obj.label)
return {result, message}
}

return {result, message}
}
}
return validatorObj.checkResult(obj)
}

export default validate

正文完
 0