感謝:尤大大的 vue、有贊的 vant佣渴、async-validator、以及 asseek
鏈接:http://www.reibang.com/p/d58fe749b97f
在下不才在 asseek 的基礎(chǔ)上加入了一些自己的想法有了現(xiàn)在的版本。
拋磚引玉請(qǐng)多多提點(diǎn)。
修正內(nèi)容:
Promise 代替 callback
添加 Proxy 實(shí)現(xiàn)校驗(yàn)的自動(dòng)觸發(fā)
精簡(jiǎn)部分代碼以期降低閱讀難度
目的:
自動(dòng)校驗(yàn)甫菠、手動(dòng)校驗(yàn)、校驗(yàn)錯(cuò)誤信息展示
/*
* @Author: 吳占超
* @Date: 2018-11-20 15:16:16
* @Last Modified by: 吳占超
* @Last Modified time: 2018-11-21 21:12:34
* 校驗(yàn)擴(kuò)展
* this.validator = new ValidatorUtils({
rules: this.rules,
data: this.formData })
this.formData = this.validator.Data
*/
import AsyncValidator from 'async-validator'
import _ from 'lodash'
/**
* 校驗(yàn)輔助類
*
* @export
* @class ValidatorUtils
*/
export default class ValidatorUtils {
/**
* Creates an instance of ValidatorUtils.
* @param {Object} rules
* @param {Object} data
* @param {Object} errMsg 錯(cuò)誤信息文本key 同data
* @param {Boolean} automatic 自動(dòng)校驗(yàn)
*
* @memberOf ValidatorUtils
*/
constructor({ rules, data, errMsg = {}, automatic = true }) {
this.setRules(rules)
this.data = data
this.errMsg = errMsg
automatic && this.setProxyValidate()
}
// #region 屬性
get Rules() {
return this.rules
}
set Data(value) {
this.data = value
}
get Data() {
return this.data
}
get Validators() {
return this.validators
}
set Validators(value) {
this.validators = value
}
set ErrMsg(value) {
this.errMsg = this.value
}
get ErrMsg() {
return this.errMsg
}
// #endregion
/**
* 自動(dòng)校驗(yàn)代理設(shè)置
*
* @returns
*
* @memberOf ValidatorUtils
*/
setProxyValidate() {
let that = this
let p = {
set(target, key, value, receiver) {
target[key] = value
that
.validate(key)
.then(result => {})
.catch(() => {})
return true
}
}
this.data = new Proxy(this.data, p)
}
/**
* 設(shè)定規(guī)則
* @param rules rules object async-validator rules
* @param cover 是否替換舊規(guī)則
*/
setRules(rules, cover = true) {
!cover || (this.Validators = {})
_(rules)
.mapKeys(
(value, key) =>
(this.Validators[key] = new AsyncValidator({ [key]: value }))
)
.value()
}
/**
* 執(zhí)行驗(yàn)證
*
* @param {String,Array} tempData 可選 傳空將驗(yàn)證構(gòu)造data 支持key王带,list<key>
* @returns Promise
*
* @memberOf ValidatorUtils
*/
validate(tempData) {
// 錯(cuò)誤數(shù)組
const err = []
let tempdata = _(this.Validators)
.keys()
.filter(
p =>
!tempData ||
(tempData &&
((_.isString(tempData) && tempData === p) ||
(_.isArray(tempData) && tempData.indexOf(p) > -1)))
)
.value()
tempdata.forEach(p =>
this.Validators[p].validate({ [p]: this.Data[p] }, error => {
error && err.push(error[0])
this.setErrMsg(p, error)
})
)
if (err.length > 0) return Promise.reject(err)
else return Promise.resolve(tempData)
}
/**
*
* 設(shè)置error消息
* @param {any} error
*
* @memberOf ValidatorUtils
*/
setErrMsg(key, error) {
this.errMsg[key] = error ? error[0].message : undefined
}
}
規(guī)則聲明:
<van-field :error-message="validator.ErrMsg.telNumber" v-model="formData.telNumber"
required clearable label="手機(jī)號(hào)"
icon="question" placeholder="請(qǐng)?zhí)顚懻_有效的手機(jī)號(hào)"
@click-icon="$toast('請(qǐng)?zhí)顚懻_有效的手機(jī)號(hào)')" />
data:()=>({
// 驗(yàn)證對(duì)象
validator: undefined,
// 表單數(shù)據(jù)源
formData: {
// 車牌號(hào)
carNumber: '魯B',
// 手機(jī)號(hào)
telNumber: undefined
},
// 校驗(yàn)
rules: {
carNumber: [
{ required: true, message: '請(qǐng)輸入魯B/魯U(kuò)開頭完整車牌號(hào)' },
{
validator: (rule, value, callBack) => {
/^[魯]{1}[B|U]{1}[A-Z0-9]{5,6}$/.test(value) ? callBack() : callBack('請(qǐng)輸入魯B/魯U(kuò)開頭完整車牌號(hào)')
}
}
],
telNumber: [
{
validator: (rule, value, callBack) => {
if (!value) {
callBack('請(qǐng)輸入手機(jī)號(hào)碼')
} else if (/^[1][0-9]{10}$/.test(value)) {
callBack()
} else {
callBack('請(qǐng)輸入正確的手機(jī)號(hào)碼')
}
}
}
]
},
......
}),
created() {
this.validator = new ValidatorUtils({
rules: this.rules,
data: this.formData })
this.formData = this.validator.Data
},