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插件jbox使用iframe关闭问题
Feb 09 Javascript
JS获取鼠标坐标的实例方法
Jul 18 Javascript
js导出table到excel同时兼容FF和IE示例
Sep 03 Javascript
基于jquery自定义的漂亮单选按钮RadioButton
Nov 19 Javascript
控制台报错object is not a function的解决方法
Aug 24 Javascript
JavaScript中的replace()方法使用详解
Jun 06 Javascript
尝试动手制作javascript放大镜效果
Dec 25 Javascript
package.json文件配置详解
Jun 15 Javascript
Angular4表单验证代码详解
Sep 03 Javascript
vue数组对象排序的实现代码
Jun 20 Javascript
vue2.0 下拉框默认标题设置方法
Aug 22 Javascript
解决vue跨域axios异步通信问题
Apr 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
了解咖啡雨林联盟认证 什么是雨林认证 雨林认证是什么意思
2021/03/05 新手入门
php把数据表导出为Excel表的最简单、最快的方法(不用插件)
2014/05/10 PHP
PHP获取当前页面URL函数实例
2014/10/22 PHP
PHP中危险的file_put_contents函数详解
2017/11/04 PHP
微信公众平台开发教程⑤ 微信扫码支付模式介绍
2019/04/10 PHP
js 替换功能函数,用正则表达式解决,js的全部替换
2010/12/08 Javascript
如何学习Javascript入门指导
2013/11/01 Javascript
js 上下左右键控制焦点(示例代码)
2013/12/14 Javascript
javascript使用onclick事件改变选中行的颜色
2013/12/30 Javascript
jQuery添加删除DOM元素方法详解
2016/01/18 Javascript
JavaScript学习笔记之数组求和方法
2016/03/23 Javascript
javascript实现仿百度图片的瀑布流加载效果
2016/04/20 Javascript
js实现做通讯录的索引滑动显示效果和滑动显示锚点效果
2017/02/18 Javascript
基于Jquery Ajax type的4种类型(详解)
2017/08/02 jQuery
ReactJs实现树形结构的数据显示的组件的示例
2017/08/18 Javascript
JS中的回调函数实例浅析
2018/03/21 Javascript
vue使用jsonp抓取qq音乐数据的方法
2018/06/21 Javascript
nodejs中实现用户注册路由功能
2019/05/20 NodeJs
node删除、复制文件或文件夹示例代码
2019/08/13 Javascript
JS用最简单的方法实现四舍五入
2019/08/27 Javascript
解决Layui中templet中a的onclick参数传递的问题
2019/09/20 Javascript
jQuery使用jsonp实现百度搜索的示例代码
2020/07/08 jQuery
Python找出微信上删除你好友的人脚本写法
2018/11/01 Python
python使用zip将list转为json的方法
2018/12/31 Python
Django之提交表单与前后端交互的方法
2019/07/19 Python
CSS3 filter(滤镜)实现网页灰色或者黑色模式的示例代码
2021/02/24 HTML / CSS
goodhealth官方海外旗舰店:新西兰国民营养师
2017/12/15 全球购物
介绍一下XMLHttpRequest对象的常用方法和属性
2013/05/24 面试题
人事部主管岗位职责
2013/12/26 职场文书
《社戏》教学反思
2014/04/15 职场文书
经济贸易系毕业生求职信
2014/05/31 职场文书
客房领班岗位职责
2015/02/11 职场文书
校园之声广播稿
2015/08/18 职场文书
严以修身专题学习研讨会发言材料
2015/11/09 职场文书
JS Object构造函数之Object.freeze
2021/04/28 Javascript
DIY胆机必读:各国电子管评价
2022/04/06 无线电