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 处理HTML元素必须避免使用的一种方法
Jul 30 Javascript
如何在父窗口中得知window.open()出的子窗口关闭事件
Oct 15 Javascript
两个多选select(multiple左右)添加、删除选项和取值实例
May 12 Javascript
jQuery中delegate()方法用法实例
Jan 19 Javascript
js实现可得到不同颜色值的颜色选择器实例
Feb 28 Javascript
Bootstrap carousel轮转图的使用实例详解
May 17 Javascript
Bootstrap基本插件学习笔记之折叠(22)
Dec 08 Javascript
JS简单实现滑动加载数据的方法示例
Oct 18 Javascript
深入浅析JSONAPI在PHP中的应用
Dec 24 Javascript
JavaScript实现轮播图效果代码实例
Sep 28 Javascript
taro小程序添加骨架屏的实现代码
Nov 15 Javascript
JS检测浏览器开发者工具是否打开的方法详解
Oct 02 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 杂谈《重构-改善既有代码的设计》之五 简化函数调用
2012/05/07 PHP
php读取远程gzip压缩网页的方法
2014/12/29 PHP
php如何连接sql server
2015/10/16 PHP
Yii框架防止sql注入,xss攻击与csrf攻击的方法
2016/10/18 PHP
JavaScript高级程序设计 读书笔记之十一 内置对象Global
2012/03/07 Javascript
jquery $.ajax相关用法分享
2012/03/16 Javascript
jQuery循环滚动新闻列表示例代码
2014/06/17 Javascript
Javascript的&amp;&amp;和||的另类用法
2014/07/23 Javascript
indexedDB bootstrap angularjs之 MVC DOMO (应用示例)
2016/06/20 Javascript
js的各种排序算法实现(总结)
2016/07/23 Javascript
javascript数字验证的实例代码(推荐)
2016/08/20 Javascript
JavaScript组成、引入、输出、运算符基础知识讲解
2016/12/08 Javascript
Javascript 实现匿名递归的实例代码
2017/05/25 Javascript
Vue.js基础指令实例讲解(各种数据绑定、表单渲染大总结)
2017/07/03 Javascript
React Native第三方平台分享的实例(Android,IOS双平台)
2017/08/04 Javascript
Es6 Generator函数详细解析
2018/02/24 Javascript
Nodejs异步回调之异常处理实例分析
2018/06/22 NodeJs
微信小程序实现批量倒计时功能
2020/11/01 Javascript
Python3学习urllib的使用方法示例
2017/11/29 Python
Flask框架web开发之零基础入门
2018/12/10 Python
python读取几个G的csv文件方法
2019/01/07 Python
python脚本实现mp4中的音频提取并保存在原目录
2020/02/27 Python
Django项目uwsgi+Nginx保姆级部署教程实现
2020/04/19 Python
美国地毯购买网站:Rugs USA
2019/02/23 全球购物
毕业大学生自荐信
2014/06/17 职场文书
党员个人批评与自我批评
2014/10/14 职场文书
2015年学校总务处工作总结
2015/05/19 职场文书
职工食堂管理制度
2015/08/06 职场文书
公司转让协议书
2016/03/19 职场文书
如何书写你的职业生涯规划书?
2019/06/27 职场文书
2019年幼儿园家长接送责任书
2019/10/29 职场文书
Nginx服务器添加Systemd自定义服务过程解析
2021/03/31 Servers
Python opencv缺陷检测的实现及问题解决
2021/04/24 Python
CSS中Single Div 绘图技巧的实现
2021/06/18 HTML / CSS
MongoDB数据库的安装步骤
2021/06/18 MongoDB
一小时学会TensorFlow2之基本操作2实例代码
2021/09/04 Python