- 爲何要寫驗證函數
- 將驗證過程變成多個步驟
- 完成一個基本的驗證函數
以前寫項目的時候,通常都是在登陸註冊,修改密碼的時候有須要些正則的需求,因此每次用到的時候都是直接從前面的代碼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,這是由於有的時候咱們並不關心某一個數據是否填寫,但一旦填寫了,又要求符合某種規則。因此若是要驗證非空的時候,須要使用兩個驗證屬性。微信
// 驗證的方法, 返回一個布爾值 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} }
把上面的步驟拼在一塊兒,就能夠完成一個驗證函數。具體的需求和使用,能夠根據項目自定義,但思路大體是這樣的。ui
/** * 傳入驗證規則,獲得驗證結果 * @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位密碼
驗證返回結果大概長這樣:this
{result: true, message: '驗證成功'} {result: false, message: '驗證失敗提示'}
把函數放在全局,須要作驗證的地方直接調用這個函數就ojbk了。url
// 檢測號碼 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() } }