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 相关文章推荐
麦鸡的TAB切换功能结合了javascript和css
Dec 17 Javascript
基于jQuery实现的Ajax 验证用户名是否存在的实现代码
Apr 06 Javascript
弹出最简单的模式化遮罩层的js代码
Dec 04 Javascript
jQuery获取对象简单实现方法小结
Oct 30 Javascript
jQuery实现悬浮在右上角的网页客服效果代码
Oct 24 Javascript
多功能jQuery树插件zTree实现权限列表简单实例
Jul 12 Javascript
Bootstrap框架结合jQuery仿百度换肤功能实例解析
Sep 17 Javascript
教大家轻松制作Bootstrap漂亮表格(table)
Dec 13 Javascript
详解bootstrap的modal-remote两种加载方式【强化】
Jan 27 Javascript
浅谈$_FILES数组为空的原因
Feb 16 Javascript
JS实现微信摇一摇原理解析
Jul 22 Javascript
js简单粗暴的发布订阅示例代码
Jan 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图片处理之使用imagecopy函数添加图片水印实例
2014/11/19 PHP
将FCKeditor导入PHP+SMARTY的实现方法
2015/01/15 PHP
CodeIgniter表单验证方法实例详解
2016/03/03 PHP
Smarty环境配置与使用入门教程
2016/05/11 PHP
js以对象为索引的关联数组
2010/07/04 Javascript
jQuery新闻滚动插件 jquery.roller.js
2011/06/27 Javascript
js判断生效时间不得大于失效时间的思路及代码
2013/04/23 Javascript
jQuery超酷平面式时钟效果代码分享
2020/03/30 Javascript
深入学习AngularJS中数据的双向绑定机制
2016/03/04 Javascript
微信小程序 教程之引用
2016/10/18 Javascript
简单实现node.js图片上传
2016/12/18 Javascript
js实现简易垂直滚动条
2017/02/22 Javascript
获取当前按钮或者html的ID名称实例(推荐)
2017/06/23 Javascript
Bootstrap实现翻页效果
2017/11/27 Javascript
Vue请求JSON Server服务器数据的实现方法
2018/11/02 Javascript
Vue实现push数组并删除的例子
2019/11/01 Javascript
在Python的Django框架中用流响应生成CSV文件的教程
2015/05/02 Python
Python端口扫描简单程序
2016/11/10 Python
Python 模拟购物车的实例讲解
2017/09/11 Python
Python3简单实例计算同花的概率代码
2017/12/06 Python
Python安装pycurl失败的解决方法
2018/10/15 Python
Django Rest framework之认证的实现代码
2018/12/17 Python
给Python学习者的文件读写指南(含基础与进阶)
2020/01/29 Python
python GUI库图形界面开发之PyQt5输入对话框QInputDialog详细使用方法与实例
2020/02/27 Python
Django中的session用法详解
2020/03/09 Python
python+selenium爬取微博热搜存入Mysql的实现方法
2021/01/27 Python
sealed修饰符是干什么的
2012/10/23 面试题
班组长的岗位职责
2013/12/09 职场文书
初二学习计划书范文
2014/04/27 职场文书
团日活动总结书格式
2014/05/08 职场文书
市场营销策划方案
2014/06/11 职场文书
放射科岗位职责
2015/02/14 职场文书
2015年社区重阳节活动总结
2015/07/30 职场文书
2016医师资格考试考生诚信考试承诺书
2016/03/25 职场文书
超市啤酒狂欢夜策划方案范文!
2019/07/03 职场文书
评测 | 大屏显示带收音机的高端音箱,JBL TUNE2便携式插卡音箱实测
2021/04/24 无线电