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 相关文章推荐
js获取图片长和宽度的代码
Nov 24 Javascript
jquery教程ajax请求json数据示例
Jan 13 Javascript
jQuery实现视频作为全屏幕背景
Dec 18 Javascript
js+html5实现canvas绘制简单矩形的方法
Jun 05 Javascript
不得不分享的JavaScript常用方法函数集(上)
Dec 23 Javascript
JavaScript在form表单中使用button按钮实现submit提交方法
Jan 23 Javascript
JS如何设置元素样式的方法示例
Aug 28 Javascript
Vue表单之v-model绑定下拉列表功能
May 14 Javascript
vue+element模态框中新增模态框和删除功能
Jun 11 Javascript
Vue 实例事件简单示例
Sep 19 Javascript
Vue父组件监听子组件生命周期
Sep 03 Javascript
微信小程序实现底部弹出框
Nov 18 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
骨王战斗力在公会成员中排不进前五,却当选了会长,原因竟是这样
2020/03/02 日漫
php checkbox复选框值的获取与checkbox默认值输出方法
2010/05/15 PHP
php学习之数据类型之间的转换代码
2011/05/29 PHP
Yii2隐藏frontend/web和backend/web的方法
2015/12/12 PHP
浅谈Jquery为元素绑定事件
2015/04/27 Javascript
jQuery.extend 函数及用法详细
2015/09/06 Javascript
JavaScript模块化开发之SeaJS
2015/12/13 Javascript
JavaScript实现搜索框的自动完成功能(一)
2016/02/25 Javascript
原生JS实现旋转木马式图片轮播插件
2016/04/25 Javascript
node.JS md5加密中文与php结果不一致的解决方法
2017/05/05 Javascript
jquery版轮播图效果和extend扩展
2017/07/18 jQuery
iView-admin 动态路由问题的解决方法
2018/10/03 Javascript
elementUI vue this.$confirm 和el-dialog 弹出框 移动 示例demo
2019/07/03 Javascript
微信JS-SDK实现微信会员卡功能(给用户微信卡包里发送会员卡)
2019/07/25 Javascript
JS实现音量控制拖动
2020/01/15 Javascript
浅析JS中NEW的实现原理及重写
2020/02/20 Javascript
python正则表达式re模块详解
2014/06/25 Python
举例详解Python中的split()函数的使用方法
2015/04/07 Python
python协程用法实例分析
2015/06/04 Python
Python编程实现生成特定范围内不重复多个随机数的2种方法
2017/04/14 Python
tensorflow获取变量维度信息
2018/03/10 Python
Python这样操作能存储100多万行的xlsx文件
2019/04/16 Python
Django重设Admin密码过程解析
2020/02/10 Python
python字符串判断密码强弱
2020/03/18 Python
python线程池 ThreadPoolExecutor 的用法示例
2020/10/10 Python
基于Python模拟浏览器发送http请求
2020/11/06 Python
calendar在python3时间中常用函数举例详解
2020/11/18 Python
CSS3实现各种图形的示例代码
2016/10/19 HTML / CSS
Zipadee-Zip襁褓过渡毯:Sleeping Baby
2018/12/30 全球购物
电子狗项圈:eDog Australia
2019/12/04 全球购物
PHP高级工程师面试问题推荐
2013/01/18 面试题
四风查摆剖析材料
2014/10/10 职场文书
投资意向协议书
2015/01/29 职场文书
三下乡个人总结
2015/03/04 职场文书
护士旷工检讨书
2015/08/15 职场文书
励志语录:时光飞逝,请学会珍惜所有的人和事
2020/01/16 职场文书