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 跨域访问问题解决方法
Dec 02 Javascript
jQuery在vs2008及js文件中的无智能提示的解决方法
Dec 30 Javascript
jquery复选框多选赋值给文本框的方法
Jan 27 Javascript
AngularJS应用开发思维之依赖注入3
Aug 19 Javascript
前端实现文件的断点续传(前端文件提交+后端PHP文件接收)
Nov 04 Javascript
详解MVC如何使用开源分页插件(shenniu.pager.js)
Dec 16 Javascript
js+canvas实现滑动拼图验证码功能
Mar 26 Javascript
微信小程序外卖选购页实现切换分类与数量加减功能案例
Jan 15 Javascript
详解基于 Node.js 的轻量级云函数功能实现
Jul 08 Javascript
vue中动态select的使用方法示例
Oct 28 Javascript
vue中实现弹出层动画效果的示例代码
Sep 25 Javascript
小程序中手机号识别的示例
Dec 14 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
国产动画《伍六七》原声大碟大卖,啊哈娱乐引领音乐赋能IP的新尝试
2020/03/08 国漫
PHP 获取客户端真实IP地址多种方法小结
2010/05/15 PHP
PHP使用DES进行加密与解密的方法详解
2013/06/06 PHP
php文件缓存类用法实例分析
2015/04/22 PHP
php自定义截取中文字符串-utf8版
2017/02/27 PHP
ThinkPHP3.2.3框架实现的空模块、空控制器、空操作,跳转到错误404页面图文详解
2019/04/03 PHP
javascript一些不错的函数脚本代码
2008/09/10 Javascript
JavaScript CSS修改学习第一章 查找位置
2010/02/19 Javascript
使用简洁的jQuery方法实现隔行换色功能
2014/01/02 Javascript
当jQuery1.7遇上focus方法的问题
2014/01/26 Javascript
jQuery插件datatables使用教程
2016/04/21 Javascript
JS实现数字格式千分位相互转换方法
2016/08/01 Javascript
JS动态计算移动端rem的解决方案
2016/10/14 Javascript
Bootstrap导航中表单简单实现代码
2017/03/06 Javascript
JavaScript原生数组Array常用方法
2017/04/06 Javascript
seajs模块压缩问题与解决方法实例分析
2017/10/10 Javascript
详解JS判断页面是在手机端还是在PC端打开的方法
2019/04/26 Javascript
Vue.js中provide/inject实现响应式数据更新的方法示例
2019/10/16 Javascript
Python可跨平台实现获取按键的方法
2015/03/05 Python
python 性能提升的几种方法
2016/07/15 Python
python os.listdir按文件存取时间顺序列出目录的实例
2018/10/21 Python
Windows系统下PhantomJS的安装和基本用法
2018/10/21 Python
numpy向空的二维数组中添加元素的方法
2018/11/01 Python
Django 博客实现简单的全文搜索的示例代码
2020/02/17 Python
Python如何实现FTP功能
2020/05/28 Python
HTML5 video 视频标签使用介绍
2014/02/03 HTML / CSS
微信小程序canvas实现水平、垂直居中效果
2020/02/05 HTML / CSS
会计师事务所审计实习自我鉴定
2013/09/20 职场文书
小学生新年寄语
2014/04/03 职场文书
访谈节目策划方案
2014/05/15 职场文书
社会工作专业自荐信
2014/09/26 职场文书
学院党委班子四风问题自查报告及整改措施
2014/10/25 职场文书
贷款收入证明范本
2015/06/12 职场文书
合作协议书格式范本
2016/03/21 职场文书
python实现对doc、txt、xls等文档的读写操作
2022/04/02 Python
Python的property属性详细讲解
2022/04/11 Python