最近在開發一個移動端商城項目,用到了有贊的 vant ,因為最近大都采用 element ui 在做PC端的東西,對比來說,vant的完成度還是偏低了點,很多細節都雖然都實現了接口,但是想使用得自己去想辦法,沒辦法拿來即用。昨天用到 Uploader 圖片上傳 如是,提供了file回調,卻沒有提供上傳功能,我必須給他加2個函數實現axios提交才能用,還有今天用到表單驗證這塊,它的 Field組件 雖然給了error-message的錯誤提示接口,但是沒有內置表單驗證功能。
element ui 采用async-validator 實現表單驗證,我也基于這個組件進行擴展,async-validator不支持細粒化驗證,于是先對它進行擴展
validator.js
import asyncValidator from 'async-validator'class validator { /** * 構造 * @param rules object async-validator rules * @param data 初始對象 */ constructor(rules, data) { this.setData(data); this.setRules(rules); } /** * 重新定義初始對象 * 也可以直接修改實例的data * validator.data = newData * @param data */ setData(data) { this.data = data; } /** * 設定規則 * @param rules rules object async-validator rules * @param cover 是否替換舊規則 */ setRules(rules, {cover} = {}) { if (cover === undefined || cover) {  this.validators = {}; } for (let attr in rules) {  const rule = {};  rule[attr] = rules[attr];  this.validators[attr] = new asyncValidator(rule); } } /** * 執行驗證 * @param callback(errors, fields) * @param data 可選 傳空將驗證構造data 傳string或數組驗證構造data的響應字段 * 以上參數順序可互轉 */ validate(callback, data) { let cb,d; if (typeof callback === 'function' ){  cb = callback;  d = data; }else if (typeof data === 'function' ){  cb = data;  d = callback; } let _d = d; if (this.data) {  if (!d) {  _d = this.data;  } else if (typeof d === 'string') {  _d = {};  _d[d] = this.data[d]  } else if (Array.isArray(d)) {  _d = {};  d.forEach(attr => {   _d[attr] = this.data[attr]  })  } } const err = []; if (_d) {  for (let attr in _d) {  if (this.validators[attr]) {   const o = {};   o[attr] = _d[attr];   this.validators[attr].validate(o, (error) => {   if (error) {    err.push(error[0])   }   })  }  } } cb && cb(err.length > 0, err) }}export default function (rules, data) { return new validator(rules, data)}demo.vue
<template> <div> <van-cell-group>  <van-field   placeholder="名稱/姓名"   label="名稱"   v-model="data.name"   :error-message="errorMsg.name"  ></van-field>  <van-field   type="tel"   placeholder="請輸入手機號碼"   label="手機"   v-model="data.mobile"   :error-message="errorMsg.mobile"   @click-icon="data.mobile = ''"   icon="clear"  ></van-field>  <van-field   center   v-model="data.code"   label="短信驗證碼"   placeholder="請輸入驗證碼"   icon="clear"   :error-message="errorMsg.code"   @click-icon="data.code = ''"  >  <van-button   slot="button"   size="small"   :disabled="countdown > 0"   @click="sendMobileCode"   type="primary">   {{ countdown ? countdown + 's' : '發送'}}  </van-button>  </van-field> </van-cell-group> <div class="pad-all mar-top">  <van-button   block   type="primary"   @click="submit">  立即注冊  </van-button>  <van-button   block   class="mar-top"   @click="reset">  重置  </van-button> </div> </div></template><script> import {Field, CellGroup, Cell, Button, Toast} from 'vant'; import validator from './validator.js' export default { name: 'Demo', components: {  [Field.name]: Field,  [Button.name]: Button,  [Cell.name]: Cell, }, data() {  return {  countdown: 0,  data: {   name: '',   mobile: '',   code: '',  },  errorMsg: {   name: '',   mobile: '',   code: '',  },  rules: {   name: [   {required: true, message: '請輸入名稱'}   ],   mobile: [   {    validator: (rule, value, callback) => {    if (!value) {     callback('請輸入手機號碼');    } else if (/^[1][0-9]{10}$/.test(value)) {     callback();    } else {     callback('請輸入正確的手機號碼');    }    }   }   ],   code: [   {required: true, message: '請輸入驗證碼'}   ]  },  } }, methods: {  sendMobileCode() {  this.validate(errors => {   if (!errors) {   Toast('發送成功');   this.countdown = 60;   this.countdownSubtract();   }  }, 'mobile')  },  countdownSubtract() {  if (this.countdown > 0) {   setTimeout(() => {   this.countdown -= 1;   this.countdownSubtract()   }, 1000)  }  },  /**  * 清除驗證提示  * @param attrs  */  resetField(attrs) {  attrs = !attrs ? Object.keys(this.errorMsg) : ( Array.isArray(attrs) ? attrs : [attrs]);  attrs.forEach(attr => {   this.errorMsg[attr] = ''  })  },  /**  * 驗證方法  * @param callback  * @param data  */  validate(callback, data) {  this.validator.validate((errors, fields) => {   this.resetField();   if (errors) {   fields.forEach(item => {    this.errorMsg[item.field] = item.message   })   }   callback && callback(errors, fields)  }, data);  },  submit() {  this.validate((errors, fields) => {  })  },  reset() {  this.data = {   name: '',   code: '',   mobile: '',  };  this.validator.setData(this.data);  this.resetField();  }, }, created() {  this.validator = validator(this.rules, this.data); }, }</script>以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。
新聞熱點
疑難解答