使用 async-validator 编写 小程序表单实时验证组件

使用 async-validator 编写 小程序表单实时验证组件

目录

  • 前言
  • 前置知识
  • 需求简介
  • 实现思路简介
  • 主要代码
  • 程序代码地址
  • 后话

前言

由于接到 “小程序表单实时验证提示错误信息” 的需求,而翻遍网络小程序表单验证,均是使用 WxValidate 在表单提交时进行判断,不知足需求,遂自定义实现该需求。html

前置知识

  • async-validator github 地址(https://github.com/yiminghe/async-validator)由于 async-validator 能够对数据进行异步校验,而且是个很纯粹的 js 库,因此选择这个库来进行校验git

  • 拜读及分析 Element 源码-form 表单组件篇 (https://juejin.im/post/5b99ff0af265da0a8a6a9439)这篇博客浅显易懂的解释了 element 表单验证源码过程,理解了这个,对于构建组件的思路颇有建设性帮助哦 o(github

     ̄︶ ̄
    )o

  • 组件间关系(https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/relations.html) 实现 form 和 form-item 以及 form-item 和 input/picker 之间关系的文档数据库

需求简介

  1. 输入框输入或选择框选择时实时验证是否符合规范,不符合时底部显示错误提示,符合时不提示
  2. 编辑时验证后台接口返回数据是否均符合规范(历史遗留,数据库中会有不符合规范的数据),若有不符合的提示
  3. 输入框或选择框未进行操做(未获取焦点),表单提交的时候总体验证,不符合规范的均提示

实现思路简介

思路简介

实现思路均参考 Element-ui 中表单验证的思路小程序

  1. 建立 form-item 组件,做为输入框(input)和选择框(picker)的父组件,用来校验 input/picker 的合法性以及错误的显示和隐藏bash

  2. 建立 form 组件,做为多个 form-item 的父组件,用来验证全部 form-item 下的组件的合法性,均合法时返回 true,不然返回 false网络

思路简图(这里均以 input 为例)

  1. 初始化的过程
  • 在 form 的初始化过程当中,须要将内部的须要验证的子组件 form-item(带有 prop 属性的组件为须要验证的组件)储存到一个变量中,方便后期使用。异步

    这里只保存须要验证的组件能够减小没必要要的操做async

  • 在 form-item 初始化的过程当中,存储父组件 form,由于验证的时候是会须要通知 form 来验证是否已所有验证经过,来进行一些必要的操做(好比未所有经过验证,操做按钮置灰等)post

  • input 初始化的时候,存储父组件 form-item,在输入的时候,调用父组件的验证方法来验证

    在 input 输入的过程当中(oninput)进行验证,这里加下防抖,能够适当的提升性能

  1. 验证过程

input 输入后,进行验证的时候,通知 form-item 来校验,校验完毕后 ① 通知 form 来校验是否全部验证均经过 ② 如若未验证经过,显示报错提示

主要代码

  1. form.js
// 默认验证回调
  validateCallBack(flag) {
    this.triggerEvent('ruleResult', flag)
  },

  // 验证
  validate(callback = this.validateCallBack.bind(this)) {
    // 若是须要验证的childList为空,调用验证时马上返回callback
    if (this.data.childList.length === 0 && callback) callback(true)
    // 验证每个form-item是否都输入正确
    callback(this.data.childList.every(i => !i.data.validateError))
  },复制代码
  1. form-item.js
// 合并规则
getRules() {
  let formRules = this.properties.rules
  const requiredRule =
    this.properties.required !== undefined
      ? { required: !!this.properties.required, message: '请输入' }
      : []
  return [].concat(formRules || []).concat(requiredRule)
},
// 获取符合事件触发的规则
getFilteredRule(trigger) {
  const rules = this.getRules()

  return rules.filter(rule =>
    !rule.trigger || trigger === '' ? true : rule.trigger === trigger
  )
},
// 默认错误处理
errorHandle(errorMessage) {
  this.setData({
    validateError: !!errorMessage,
    validateStatus: errorMessage ? 'error' : 'success',
    validateMessage: errorMessage
  })
},
// 验证
validate(value, trigger = '', callback = this.errorHandle.bind(this)) {
  const prop = this.properties.prop
  // 没有prop,不须要验证
  if (!prop) return
  //获取合并后的规则
  const rules = this.getFilteredRule(trigger)
  // 调用AsyncValidator进行验证
  const validator = new AsyncValidator({ [prop]: rules })

  validator.validate({ [prop]: value }, { firstFields: true }, errors => {
    // 不须要校验
    if (errors === undefined) return
    const errorMessage = errors ? errors[0].message : ''
    // 显示错误提示
    callback(errorMessage)
    // 调用form的validate方法判断是否所有正确
    this.data.elForm.validate()
  })
}复制代码

程序代码地址

github 地址(https://github.com/5kinna/miniprogram-form-validate)

后话

这是第一个小程序中的需求,由于经验和能力的欠缺,难免会有不对的地方,还望大神斧正。

相关文章
相关标签/搜索