1. 程式人生 > >Vant async-validator 表單校驗

Vant async-validator 表單校驗

感謝:尤大大的 vue、有讚的 vant、async-validator、以及 asseek

連結:https://www.jianshu.com/p/d58fe749b97f

在下不才在 asseek 的基礎上加入了一些自己的想法有了現在的版本。
拋磚引玉請多多提點。

修正內容:

  1. Promise 代替 callback

  2. 新增 Proxy 實現校驗的自動觸發

  3. 精簡部分程式碼以期降低閱讀難度

目的:

自動校驗、手動校驗、校驗錯誤資訊展示

/* * @Author: 吳佔超 * @Date: 2018-11-20 15:16:16 * @Last Modified by: 吳佔超 * @Last Modified time: 2018-11-21 21:43:11 * 校驗擴充套件 * this.validator = new ValidatorUtils({ rules: this.rules, data: this.formData }) this.formData = this.validator.Data */ import AsyncValidator from 'async-validator' import _ from 'lodash' export default class ValidatorUtils { /** * Creates an instance of ValidatorUtils. * @param {Object} rules * @param {Object} data * @param {Object} errMsg 錯誤資訊文字key 同data * @param {Boolean} automatic 自動校驗 * * @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
/** * 自動校驗代理設定 * * @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) }
/** * 設定規則 * @param rules rules object async-validator rules * @param cover 是否替換舊規則 */ setRules(rules, cover = true) { !cover || (this.Validators = {}) _(rules) .mapKeys( (value, key) => (this.Validators[key] = new AsyncValidator({ [key]: value })) ) .value() }
/** * 執行驗證 * * @param {String,Array} tempData 可選 傳空將驗證構造data 支援key,list<key> * @returns Promise * * @memberOf ValidatorUtils */ validate(tempData) { // 錯誤陣列 const err = [] let that = this _(this.Validators) .keys() .filter( p => !tempData || (tempData && _(that.Data).hasIn(tempData) && ((_.isString(tempData) && tempData === p) || (_.isArray(tempData) && _(tempData).hasIn(p)))) ) .value() .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) } /** * * 設定error訊息 * @param {any} error * * @memberOf ValidatorUtils */ setErrMsg(key, error) { this.errMsg[key] = error ? error[0].message : undefined } }

規則宣告:

<van-field :error-message="validator.ErrMsg.telNumber" v-model="formData.telNumber"
required clearable label="手機號"
icon="question" placeholder="請填寫正確有效的手機號"
@click-icon="$toast('請填寫正確有效的手機號')" />

data:()=>({
// 驗證物件
validator: undefined,
// 表單資料來源
formData: {
// 車牌號
carNumber: '魯B',
// 手機號
telNumber: undefined
},
// 校驗
rules: {
carNumber: [
{ required: true, message: '請輸入魯B/魯U開頭完整車牌號' },
{
validator: (rule, value, callBack) => {
/^[魯]{1}[B|U]{1}[A-Z0-9]{5,6}$/.test(value) ? callBack() : callBack('請輸入魯B/魯U開頭完整車牌號')
}
}
],
telNumber: [
{
validator: (rule, value, callBack) => {
if (!value) {
callBack('請輸入手機號碼')
} else if (/^[1][0-9]{10}$/.test(value)) {
callBack()
} else {
callBack('請輸入正確的手機號碼')
}
}
}
]
},
......
}),
created() {
this.validator = new ValidatorUtils({
rules: this.rules,
data: this.formData })
this.formData = this.validator.Data
},