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 相关文章推荐
img onload事件绑定各浏览器均可执行
Dec 19 Javascript
html中使用javascript调用本地程序(exe、doc等)实现代码
Apr 26 Javascript
jQuery 无限级菜单的简单实例
Feb 21 Javascript
js实现跨域的多种方法
Dec 25 Javascript
基于canvas实现的绚丽圆圈效果完整实例
Jan 26 Javascript
jquery实现网页定位导航
Aug 23 Javascript
微信小程序 progress组件详解及实例代码
Oct 25 Javascript
在vue里面设置全局变量或数据的方法
Mar 09 Javascript
react native 获取地理位置的方法示例
Aug 28 Javascript
微信小程序文字显示换行问题
Jul 28 Javascript
Vue.js 无限滚动列表性能优化方案
Dec 02 Javascript
基于vue-draggable 实现三级拖动排序效果
Jan 10 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 str_pad 函数用法简介
2009/07/11 PHP
封装一个PDO数据库操作类代码
2009/09/09 PHP
win7计划任务定时执行PHP脚本设置图解
2014/05/09 PHP
php生成zip文件类实例
2015/04/07 PHP
php动态生成缩略图并输出显示的方法
2015/04/20 PHP
PHP格式化MYSQL返回float类型的方法
2016/03/30 PHP
ThinkPHP框架实现的邮箱激活功能示例
2018/06/15 PHP
Alliance vs Liquid BO3 第二场2.13
2021/03/10 DOTA
javascript优先加载笔记代码
2008/09/30 Javascript
JQuery入门——用映射方式绑定不同事件应用示例
2013/02/05 Javascript
js实现单一html页面两套css切换代码
2013/04/11 Javascript
探讨在JQuery和Js中,如何让ajax执行完后再继续往下执行
2013/07/09 Javascript
JavaScript cookie的设置获取删除详解
2014/02/11 Javascript
JavaScript判断是否为数字的4种方法及效率比较
2015/04/01 Javascript
JavaScript中String.prototype用法实例
2015/05/20 Javascript
JS实现模拟百度搜索“2012世界末日”网页地震撕裂效果代码
2015/10/31 Javascript
javascript实现网页端解压并查看zip文件
2015/12/15 Javascript
js上传图片预览的实现方法
2017/05/09 Javascript
JavaScript门面模式详解
2017/10/19 Javascript
Thinkjs3新手入门之如何使用静态资源目录
2017/12/06 Javascript
jQuery实现DIV响应鼠标滑过由下向上展开效果示例【测试可用】
2018/04/26 jQuery
Node.js模拟发起http请求从异步转同步的5种用法
2018/09/26 Javascript
微信小程序module.exports模块化操作实例浅析
2018/12/20 Javascript
微信小程序自定义带价格显示日历效果
2018/12/29 Javascript
ant-design表单处理和常用方法及自定义验证操作
2020/10/27 Javascript
使用Python制作获取网站目录的图形化程序
2015/05/04 Python
Python实现螺旋矩阵的填充算法示例
2017/12/28 Python
django admin 后台实现三级联动的示例代码
2018/06/22 Python
Python操作rabbitMQ的示例代码
2019/03/19 Python
用OpenCV将视频分解成单帧图片,图片合成视频示例
2019/12/10 Python
Python中logging日志记录到文件及自动分割的操作代码
2020/08/05 Python
如何设置Java的运行环境
2013/04/05 面试题
健康家庭事迹材料
2014/05/02 职场文书
公司户外活动总结
2014/07/04 职场文书
小学师德师风演讲稿
2014/09/02 职场文书
python实现socket简单通信的示例代码
2021/04/13 Python