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 相关文章推荐
JavaScript入门教程(8) Location地址对象
Jan 31 Javascript
用于节点操作的API,颠覆原生操作HTML DOM节点的API
Dec 11 Javascript
由Javascript实现的页面日历
Nov 04 Javascript
用js格式化金额可设置保留的小数位数
May 09 Javascript
jquery 页眉单行信息滚动显示实现思路及代码
Jun 26 Javascript
JsRender实用入门教程
Oct 31 Javascript
javascript关于运动的各种问题经典总结
Apr 27 Javascript
跟我学习javascript的严格模式
Nov 16 Javascript
jQuery无缝轮播图代码
Dec 22 Javascript
用 js 的 selection range 操作选择区域内容和图片
Apr 18 Javascript
详解AngularJS跨页面传值(ui-router)
Aug 23 Javascript
vue中重定向redirect:‘/index‘,不显示问题、跳转出错的完美解决
Sep 28 Javascript
使用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
基于qmail的完整WEBMAIL解决方案安装详解
2006/10/09 PHP
PHP+AJAX实现无刷新注册(带用户名实时检测)
2007/01/02 PHP
php实现指定字符串中查找子字符串的方法
2015/03/17 PHP
用jscript实现新建word文档
2007/06/15 Javascript
用倒置滤镜把div倒置,再把table倒置。
2007/07/31 Javascript
JavaScript this 深入理解
2009/07/30 Javascript
AppBaseJs 类库 网上常用的javascript函数及其他js类库写的
2010/03/04 Javascript
JavaScript实现为指定对象添加多个事件处理程序的方法
2015/04/17 Javascript
jquery实现多屏多图焦点图切换特效的方法
2015/05/04 Javascript
nodejs导出excel的方法
2015/06/30 NodeJs
使用CoffeeScrip优美方式编写javascript代码
2015/10/28 Javascript
Spring MVC中Ajax实现二级联动的简单实例
2016/07/06 Javascript
JavaScript实现分页效果
2017/03/28 Javascript
强大的 Angular 表单验证功能详细介绍
2017/05/23 Javascript
Vue.js表单标签中的单选按钮、复选按钮和下拉列表的取值问题
2017/11/22 Javascript
vue.js,ajax渲染页面的实例
2018/02/11 Javascript
JavaScript 2018 中即将迎来的新功能
2018/09/21 Javascript
[01:03:41]DOTA2-DPC中国联赛 正赛 Dynasty vs XG BO3 第三场 2月2日
2021/03/11 DOTA
跟老齐学Python之使用Python操作数据库(1)
2014/11/25 Python
Python脚本实现集群检测和管理功能
2015/03/06 Python
python获取指定路径下所有指定后缀文件的方法
2015/05/26 Python
利用Pandas 创建空的DataFrame方法
2018/04/08 Python
Python计算一个给定时间点前一个月和后一个月第一天的方法
2018/05/29 Python
python使用matplotlib画饼状图
2018/09/25 Python
基于python traceback实现异常的获取与处理
2019/12/13 Python
Python爬虫库requests获取响应内容、响应状态码、响应头
2020/01/25 Python
用纯css3实现的图片放大镜特效效果非常不错
2014/09/02 HTML / CSS
英国口碑最好的的维他命胶囊品牌:Myvitamins(有中文站)
2016/12/03 全球购物
阿里旅行:飞猪
2017/01/05 全球购物
安全大检查实施方案
2014/02/22 职场文书
父母对孩子说的话
2014/04/12 职场文书
小学学习雷锋活动总结
2014/07/03 职场文书
反对四风自我剖析材料
2014/10/07 职场文书
公司聚餐通知
2015/04/22 职场文书
2016医师资格考试考生诚信考试承诺书
2016/03/25 职场文书
centos环境下nginx高可用集群的搭建指南
2022/07/23 Servers