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 相关文章推荐
基于JQuery的cookie插件
Apr 07 Javascript
深入理解JavaScript系列(14) 作用域链介绍(Scope Chain)
Apr 12 Javascript
jQuery源码中的chunker 正则过滤符分析
Jul 31 Javascript
JQuery 图片滚动轮播示例代码
Mar 24 Javascript
jquery选择器原理介绍($()使用方法)
Mar 25 Javascript
Javascript中的几种URL编码方法比较
Jan 23 Javascript
Web打印解决方案之证件套打的实现思路
Aug 29 Javascript
js实现选项卡内容切换以及折叠和展开效果【推荐】
Jan 08 Javascript
浅谈webpack SplitChunksPlugin实用指南
Sep 17 Javascript
使用kbone解决Vue项目同时支持小程序问题
Nov 08 Javascript
jQuery操作元素的内容和样式完整实例分析
Jan 10 jQuery
使用next.js开发网址缩短服务的方法
Jun 17 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
用PHP动态生成虚拟现实VRML网页
2006/10/09 PHP
简单的php缓存类分享     php缓存机制
2014/01/22 PHP
PHP实现股票趋势图和柱形图
2015/02/07 PHP
Linux下源码包安装Swoole及基本使用操作图文详解
2019/04/02 PHP
php转换上传word文件为PDF的方法【基于COM组件】
2019/06/10 PHP
Laravel框架源码解析之模型Model原理与用法解析
2020/05/14 PHP
一个用js实现的页内搜索代码
2007/05/23 Javascript
Javascript Request获取请求参数如何实现
2012/11/28 Javascript
JS 去前后空格大全(IE9亲测)
2013/07/15 Javascript
js判断屏幕分辨率的代码
2013/07/16 Javascript
用JavaScript实现用一个DIV来包装文本元素节点
2014/09/09 Javascript
javascript下拉列表菜单的实现方法
2015/11/18 Javascript
jQuery实现鼠标选文字发新浪微博的方法
2016/04/02 Javascript
Javascript 获取鼠标当前的位置实现方法
2016/10/27 Javascript
vue 怎么创建组件及组件使用方法
2017/07/27 Javascript
Vue.js 实现数据展示全部和收起功能
2018/09/05 Javascript
Puppeteer 爬取动态生成的网页实战
2018/11/14 Javascript
VUE2.0+ElementUI2.0表格el-table实现表头扩展el-tooltip
2018/11/30 Javascript
如何在JavaScript中创建具有多个空格的字符串?
2020/02/23 Javascript
Vue中用JSON实现刷新界面不影响倒计时
2020/10/26 Javascript
在Python中操作列表之List.append()方法的使用
2015/05/20 Python
简述Python2与Python3的不同点
2018/01/21 Python
pandas全表查询定位某个值所在行列的方法
2018/04/12 Python
pandas带有重复索引操作方法
2018/06/08 Python
HTML5的结构和语义(3):语义性的块级元素
2008/10/17 HTML / CSS
香港优质食材和美酒专门店:FoodWise
2017/09/01 全球购物
Dillard’s百货官网:Dillards.com
2018/05/26 全球购物
数据库设计的包括哪两种,请分别进行说明
2016/07/15 面试题
会计专业毕业生自我鉴定
2013/10/29 职场文书
精通CAD能手自荐书
2014/01/31 职场文书
会计专业个人自我鉴定
2014/03/21 职场文书
2014年志愿者工作总结
2014/11/20 职场文书
年底个人总结范文
2015/03/10 职场文书
2015年秋季学校开学标语
2015/07/16 职场文书
小学数学继续教育研修日志
2015/11/13 职场文书
jQuery实现影院选座订座效果
2021/04/13 jQuery