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对象的property属性详解
Apr 01 Javascript
javascript中的throttle和debounce浅析
Jun 06 Javascript
简洁实用的BootStrap jQuery手风琴插件
Aug 31 Javascript
利用Node.JS实现邮件发送功能
Oct 21 Javascript
svg动画之动态描边效果
Feb 22 Javascript
基于bootstrap实现多个下拉框同时搜索功能
Jul 19 Javascript
JavaScript实现重力下落与弹性效果的方法分析
Dec 20 Javascript
Echart折线图手柄触发事件示例详解
Dec 16 Javascript
vue轻量级框架无法获取到vue对象解决方法
May 12 Javascript
js中apply和call的理解与使用方法
Nov 27 Javascript
原生JS运动实现轮播图
Jan 02 Javascript
JS前端宏任务微任务及Event Loop使用详解
Jul 23 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 配置文件中open_basedir选项作用
2009/07/19 PHP
PHP CKEditor 上传图片实现代码
2009/11/06 PHP
PHP可逆加密/解密函数分享
2012/09/25 PHP
php计算两个坐标(经度,纬度)之间距离的方法
2015/04/17 PHP
PHP也能干大事之PHP中的编码解码详解
2015/04/20 PHP
PHP基于自定义函数生成笛卡尔积的方法示例
2017/09/30 PHP
laravel框架select2多选插件初始化默认选中项操作示例
2020/02/18 PHP
PHP设计模式(七)组合模式Composite实例详解【结构型】
2020/05/02 PHP
如何使用JS获取IE上传文件路径(IE7,8)
2013/07/08 Javascript
jquery日历控件实现方法分享
2014/03/07 Javascript
JavaScript高级程序设计(第三版)学习笔记1~5章
2016/03/11 Javascript
JavaScript学习笔记整理_用于模式匹配的String方法
2016/09/19 Javascript
微信小程序 css使用技巧总结
2017/01/09 Javascript
Bootstrap BootstrapDialog使用详解
2017/02/17 Javascript
使用jQuery,Angular实现登录界面验证码详解
2017/04/27 jQuery
vue2.0学习之axios的封装与vuex介绍
2018/05/28 Javascript
vue 实现在函数中触发路由跳转的示例
2018/09/01 Javascript
JS实现二维数组元素的排列组合运算简单示例
2019/01/28 Javascript
JS学习笔记之闭包小案例分析
2019/05/29 Javascript
Vue2.0实现简单分页及跳转效果
2019/07/29 Javascript
基于jQuery实现可编辑的表格
2019/12/11 jQuery
python利用正则表达式搜索单词示例代码
2017/09/24 Python
Python实现string字符串连接的方法总结【8种方式】
2018/07/06 Python
Flask框架学习笔记之使用Flask实现表单开发详解
2019/08/12 Python
Django通过dwebsocket实现websocket的例子
2019/11/15 Python
python中sort sorted reverse reversed函数的区别说明
2020/05/11 Python
美国优质马术服装购买网站:Breeches.com
2019/12/16 全球购物
附答案的Java面试题
2012/11/19 面试题
交通事故一次性赔偿协议书范本
2014/11/02 职场文书
申报材料格式
2014/12/30 职场文书
班级元旦晚会开幕词
2015/01/29 职场文书
会议通知格式范文
2015/04/15 职场文书
2015年班主任德育工作总结
2015/05/21 职场文书
学校教师培训工作总结
2015/10/14 职场文书
深入详解JS函数的柯里化
2021/06/09 Javascript
centos环境下nginx高可用集群的搭建指南
2022/07/23 Servers