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 相关文章推荐
ASP.NET jQuery 实例5 (显示CheckBoxList成员选中的内容)
Jan 13 Javascript
JQuery切换显示的效果实例代码
Feb 27 Javascript
javascript中hasOwnProperty() 方法使用指南
Mar 09 Javascript
基于JavaScript FileReader上传图片显示本地链接
May 27 Javascript
表单input项使用label同时引用Bootstrap库导致input点击效果区增大问题
Oct 11 Javascript
Angularjs中ng-repeat-start与ng-repeat-end的用法实例介绍
Dec 31 Javascript
深入理解ES7的async/await的用法
Sep 09 Javascript
Vue前端开发规范整理(推荐)
Apr 23 Javascript
jQuery实现常见的隐藏与展示列表效果示例
Jun 04 jQuery
默认浏览器设置及vue自动打开页面的方法
Sep 21 Javascript
简谈创建React Component的几种方式
Jun 15 Javascript
JS前端使用Canvas快速实现手势解锁特效
Sep 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中几种常见安全设置详解
2010/04/06 PHP
PHP中把错误日志保存在系统日志中(Windows系统)
2015/06/23 PHP
PHP实现支持CURL字符串证书传输的方法
2019/03/23 PHP
laravel Task Scheduling(任务调度)在windows下的使用详解
2019/10/22 PHP
关于图片验证码设计的思考
2007/01/29 Javascript
jQuery EasyUI API 中文文档 - Documentation 文档
2011/09/29 Javascript
JS父页面与子页面相互传值方法
2014/03/05 Javascript
jQuery中Ajax的get、post等方法详解
2015/01/20 Javascript
JavaScript判断数组是否包含指定元素的方法
2015/07/01 Javascript
javascript实现简单的分页特效
2015/08/12 Javascript
jQuery编程中的一些核心方法简介
2015/08/14 Javascript
JS简单实现城市二级联动选择插件的方法
2015/08/19 Javascript
jquery实现的判断倒计时是否结束代码
2016/02/05 Javascript
原生Javascript插件开发实践
2017/01/09 Javascript
JavaScript之underscore_动力节点Java学院整理
2017/07/03 Javascript
Node.js学习教程之HTTP/2服务器推送【译】
2017/10/31 Javascript
jquery实现垂直手风琴导航栏
2020/02/18 jQuery
用云开发Cloudbase实现小程序多图片内容安全监测的代码详解
2020/06/07 Javascript
浅谈Python中chr、unichr、ord字符函数之间的对比
2016/06/16 Python
Python之web模板应用
2017/12/26 Python
python中使用 xlwt 操作excel的常见方法与问题
2019/01/13 Python
如何通过python画loss曲线的方法
2019/06/26 Python
Python实现UDP程序通信过程图解
2020/05/15 Python
CSS3教程(10):CSS3 HSL声明设置颜色
2009/04/02 HTML / CSS
css3强大的动画效果animate使用说明及浏览器兼容介绍
2013/01/09 HTML / CSS
欧舒丹英国官网:购买欧舒丹护手霜等明星产品
2017/01/17 全球购物
ROSEFIELD手表荷兰官方网上商店:北欧极简设计女士腕表品牌
2018/01/24 全球购物
德国圣伯纳德草药屋:Kräuterhaus Sanct Bernhard(有中文站)
2018/08/05 全球购物
几个人围成一圈的问题
2013/09/26 面试题
法学毕业生自荐信
2013/11/13 职场文书
仓库保管员岗位职责
2013/12/20 职场文书
小班重阳节活动方案
2014/02/08 职场文书
质量保证书格式模板
2015/02/27 职场文书
结婚主持人致辞
2015/07/28 职场文书
python 爬取吉首大学网站成绩单
2021/06/02 Python
SQL Server使用CROSS APPLY与OUTER APPLY实现连接查询
2022/05/25 SQL Server