vant(ZanUi)结合async-validator实现表单验证的方法


Posted in Javascript onDecember 06, 2018

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

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

Javascript 相关文章推荐
MSN消息提示类
Sep 05 Javascript
javascript 主动派发事件总结
Aug 09 Javascript
jquery获得keycode的示例代码
Dec 30 Javascript
javascript屏蔽右键代码
May 15 Javascript
jQuery CSS()方法改变现有的CSS样式表
Sep 09 Javascript
JavaScript 身份证号有效验证详解及实例代码
Oct 20 Javascript
jQuery插件FusionCharts绘制2D双折线图效果示例【附demo源码】
Apr 14 jQuery
jQuery实现IE输入框完成placeholder标签功能的方法
Sep 20 jQuery
vue.js element-ui tree树形控件改iview的方法
Mar 29 Javascript
jquery轻量级数字动画插件countUp.js使用详解
Oct 17 jQuery
js实现鼠标拖曳效果
Dec 30 Javascript
vue+iview实现手机号分段输入框
Mar 25 Vue.js
使用react render props实现倒计时的示例代码
Dec 06 #Javascript
微信小程序冒泡事件及其阻止方法实例分析
Dec 06 #Javascript
谈谈React中的Render Props模式
Dec 06 #Javascript
详解Vue-axios 设置请求头问题
Dec 06 #Javascript
超好用的jQuery分页插件jpaginate用法示例【附源码下载】
Dec 06 #jQuery
jQuery动态操作表单示例【基于table表格】
Dec 06 #jQuery
js防抖和节流的深入讲解
Dec 06 #Javascript
You might like
超级简单的发送邮件程序
2006/10/09 PHP
PHP 计算至少是其他数字两倍的最大数的实现代码
2020/05/26 PHP
javascript读取xml
2006/11/04 Javascript
网页加载时页面显示进度条加载完成之后显示网页内容
2012/12/23 Javascript
javascript判断office版本示例
2014/04/11 Javascript
jquery实现带渐变淡入淡出并向右依次展开的多级菜单效果实例
2015/08/22 Javascript
基于Jquery代码实现手风琴菜单
2015/11/19 Javascript
js点击文本框弹出可选择的checkbox复选框
2016/02/03 Javascript
JS中改变this指向的方法(call和apply、bind)
2016/03/26 Javascript
JavaScript中的原型prototype完全解析
2016/05/10 Javascript
AngularJS入门教程之表格实例详解
2016/07/27 Javascript
js修改onclick动作的四种方法(推荐)
2016/08/18 Javascript
jQuery实现 上升、下降、删除、添加一行代码
2017/03/06 Javascript
Angular实现可删除并计算总金额的购物车功能示例
2017/12/26 Javascript
vue-cli V3.0版本的使用详解
2018/10/24 Javascript
vue项目搭建以及全家桶的使用详细教程(小结)
2018/12/19 Javascript
Easyui 关闭jquery-easui tab标签页前触发事件的解决方法
2019/04/28 jQuery
Node 代理访问的实现
2019/09/19 Javascript
Layui数据表格判断编辑输入的值,是否为我需要的类型详解
2019/10/26 Javascript
详解Howler.js Web音频播放终极解决方案
2020/08/23 Javascript
Python使用Redis实现作业调度系统(超简单)
2016/03/22 Python
利用python将xml文件解析成html文件的实现方法
2017/12/22 Python
详解python 3.6 安装json 模块(simplejson)
2019/04/02 Python
Django基础知识 URL路由系统详解
2019/07/18 Python
Python在后台自动解压各种压缩文件的实现方法
2020/11/10 Python
HTML5 Geolocation API的正确使用方法
2018/12/04 HTML / CSS
丝芙兰新加坡官网:Sephora新加坡
2018/12/04 全球购物
志愿者服务感言
2014/02/27 职场文书
反邪教警示教育方案
2014/05/13 职场文书
服装设计专业自荐信
2014/06/17 职场文书
先进党支部事迹材料
2014/12/24 职场文书
万能检讨书开头与结尾怎么写
2015/02/17 职场文书
人代会简报
2015/07/21 职场文书
祝福语集锦:送给闺蜜的生日祝福语
2019/10/08 职场文书
导游词之山西祁县乔家大院
2019/10/14 职场文书
python开发制作好看的时钟效果
2022/05/02 Python