使用 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)

後話

這是第一個小程序中的需求,由於經驗和能力的欠缺,難免會有不對的地方,還望大神斧正。

相關文章
相關標籤/搜索