最近在开发一个移动端商城项目,用到了有赞的 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   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   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>
< >
 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 ?  .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);
 },
 }
</ >

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

收藏 打印