由於接到 「小程序表單實時驗證提示錯誤信息」 的需求,而翻遍網絡小程序表單驗證,均是使用 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
組件間關係(https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/relations.html) 實現 form 和 form-item 以及 form-item 和 input/picker 之間關係的文檔數據庫
實現思路均參考 Element-ui 中表單驗證的思路小程序
建立 form-item 組件,做爲輸入框(input)和選擇框(picker)的父組件,用來校驗 input/picker 的合法性以及錯誤的顯示和隱藏bash
建立 form 組件,做爲多個 form-item 的父組件,用來驗證全部 form-item 下的組件的合法性,均合法時返回 true,不然返回 false網絡
在 form 的初始化過程當中,須要將內部的須要驗證的子組件 form-item(帶有 prop 屬性的組件爲須要驗證的組件)儲存到一個變量中,方便後期使用。異步
這裏只保存須要驗證的組件能夠減小沒必要要的操做async
在 form-item 初始化的過程當中,存儲父組件 form,由於驗證的時候是會須要通知 form 來驗證是否已所有驗證經過,來進行一些必要的操做(好比未所有經過驗證,操做按鈕置灰等)post
input 初始化的時候,存儲父組件 form-item,在輸入的時候,調用父組件的驗證方法來驗證
在 input 輸入的過程當中(oninput)進行驗證,這裏加下防抖,能夠適當的提升性能
input 輸入後,進行驗證的時候,通知 form-item 來校驗,校驗完畢後 ① 通知 form 來校驗是否全部驗證均經過 ② 如若未驗證經過,顯示報錯提示
// 默認驗證回調
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))
},複製代碼
// 合併規則
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)
這是第一個小程序中的需求,由於經驗和能力的欠缺,難免會有不對的地方,還望大神斧正。