- 爲何要寫驗證函數
- 將驗證過程變成多個步驟
- 完成一個基本的驗證函數
以前寫項目的時候,通常都是在登陸註冊,修改密碼的時候有須要些正則的需求,因此每次用到的時候都是直接從前面的代碼copy過去就行了,直到後臺開始寫後臺管理系統類的項目,複製粘貼已經徹底不可行了。怎麼能作一個只會ctrl+c,ctrl+v的程序猿呢!簡直不能忍,因而就想到了本身寫一個驗證函數,每次須要作驗證的時候只須要調用這個函數,傳入參數就能夠了,想一想都美滋滋。git
作驗證的時候咱們要作的,定義驗證失敗後的提示,編寫驗證的方法,而後調用驗證獲得結果。 一個驗證的過程,通常即是分爲這幾步,咱們能夠按照這個步驟設計出本身的驗證函數。github
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,這是由於有的時候咱們並不關心某一個數據是否填寫,但一旦填寫了,又要求符合某種規則。因此若是要驗證非空的時候,須要使用兩個驗證屬性。bash
// 驗證的方法, 返回一個布爾值
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]]) {
console.log(obj.rules[i] + '規則不存在')
break
}
// 獲得當前驗證失敗信息
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}
}
複製代碼
把上面的步驟拼在一塊兒,就能夠完成一個驗證函數。具體的需求和使用,能夠根據項目自定義,但思路大體是這樣的。函數
/**
* 傳入驗證規則,獲得驗證結果
* @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
複製代碼
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位密碼
複製代碼
驗證返回結果大概長這樣:ui
{result: true, message: '驗證成功'}
{result: false, message: '驗證失敗提示'}
複製代碼
把函數放在全局,須要作驗證的地方直接調用這個函數就ojbk了。this
// 檢測號碼
const checkMobile = (rule, value, callback) => {
let check = this.$validate({label: '號碼', value, rules: ['moblie']})
if (!check.result) {
callback(new Error(check.message))
} else {
callback()
}
}
// 檢測非中文
const checkWechat = (rule, value, callback) => {
let check = this.$validate({label: '微信', value, rules: ['noChinese', 'max'], conditions: [12]})
if (!check.result) {
callback(new Error(check.message))
} else {
callback()
}
}
複製代碼
源碼---如何使用url