您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)使用async-validator怎么編寫一個(gè)Form組件,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。
1. async-validator 的基本用法
async-validator 的功能是校驗(yàn)數(shù)據(jù)是否合法,并且根據(jù)校驗(yàn)規(guī)則給出提示信息。
下面演示一下 async-validator 的最基本用法。
import AsyncValidator from 'async-validator' // 校驗(yàn)規(guī)則 const descriptor = { username: [ { required: true, message: '請(qǐng)?zhí)顚懹脩裘?#39; }, { min: 3, max: 10, message: '用戶名長(zhǎng)度為3-10' } ] } // 根據(jù)校驗(yàn)規(guī)則構(gòu)造一個(gè) validator const validator = new AsyncValidator(descriptor) const data = { username: 'username' } validator.validate(model, (errors, fields) => { console.log(errors) })
當(dāng)數(shù)據(jù)不符合校驗(yàn)規(guī)則時(shí),在 validator.validate 的回調(diào)函數(shù)中,就可以得到相應(yīng)的錯(cuò)誤信息。
當(dāng) async-validator 中常見的校驗(yàn)規(guī)則無(wú)法滿足需求時(shí),我們可以編寫自定義的校驗(yàn)函數(shù)來(lái)校驗(yàn)數(shù)據(jù)。一個(gè)簡(jiǎn)單的校驗(yàn)函數(shù)如下。
function validateData (rule, value, callback) { let err if (value === 'xxxx') { err = '不符合規(guī)范' } callback(err) } const descriptor = { complex: [ { validator: validateData } ] } const validator = new AsyncValidator(descriptor)
async-validator 支持對(duì)數(shù)據(jù)異步校驗(yàn),所以在編寫自定義校驗(yàn)函數(shù)時(shí),不管校驗(yàn)是否通過,校驗(yàn)函數(shù)中的 callback 都要調(diào)用。
現(xiàn)在知道了 async-validator 的使用方法,如何將這個(gè)庫(kù)跟要編寫的 Form 組件結(jié)合起來(lái)呢。
實(shí)現(xiàn)思路
用一張圖描述一下實(shí)現(xiàn)思路。
Form 組件
Form 組件應(yīng)該是一個(gè)容器,里面包含不定數(shù)量的 FormItem 或者其他元素??梢允褂?Vue 內(nèi)置的slot 組件來(lái)代表 Form 里面的內(nèi)容。
Form 組件還需要知道包含了多少個(gè)需要校驗(yàn)的 FormItem 組件。一般情況下,父子組件的通信 是通過在子組件上綁定事件實(shí)現(xiàn)的,但是這里使用 slot,無(wú)法監(jiān)聽到子組件的事件。這里可以在 Form 組件上通過$on 監(jiān)聽事件,F(xiàn)ormItem 掛載或者銷毀前觸發(fā) Form 組件的自定義事件即可。
按照這個(gè)思路,我們先編寫 Form 組件。
<template> <form class="v-form"> <slot></slot> </form> </template> <script> import AsyncValidator from 'async-validator' export default { name: 'v-form', componentName: 'VForm', // 通過 $options.componentName 來(lái)找 form 組件 data () { return { fields: [], // field: {prop, el},保存 FormItem 的信息。 formError: {} } }, computed: { formRules () { const descriptor = {} this.fields.forEach(({prop}) => { if (!Array.isArray(this.rules[prop])) { console.warn(`prop 為 ${prop} 的 FormItem 校驗(yàn)規(guī)則不存在或者其值不是數(shù)組`) descriptor[prop] = [{ required: true }] return } descriptor[prop] = this.rules[prop] }) return descriptor }, formValues () { return this.fields.reduce((data, {prop}) => { data[prop] = this.model[prop] return data }, {}) } }, methods: { validate (callback) { const validator = new AsyncValidator(this.formRules) validator.validate(this.formValues, (errors) => { let formError = {} if (errors && errors.length) { errors.forEach(({message, field}) => { formError[field] = message }) } else { formError = {} } this.formError = formError // 讓錯(cuò)誤信息的順序與表單組件的順序相同 const errInfo = [] this.fields.forEach(({prop, el}, index) => { if (formError[prop]) { errInfo.push(formError[prop]) } }) callback(errInfo) }) } }, props: { model: Object, rules: Object }, created () { this.$on('form.addField', (field) => { if (field) { this.fields = [...this.fields, field] } }) this.$on('form.removeField', (field) => { if (field) { this.fields = this.fields.filter(({prop}) => prop !== field.prop) } }) } } </script>
FormItem 組件
FormItem 組件就簡(jiǎn)單很多,首先要向上找到包含它的 Form 組件。接下來(lái)就可以根據(jù) formError 計(jì)算出對(duì)應(yīng)的錯(cuò)誤信息。
<template> <div class="form-item"> <label :for="prop" class="form-item-label" v-if="label"> {{ label }} </label> <div class="form-item-content"> <slot></slot> </div> </div> </template> <script> export default { name: 'form-item', computed: { form () { let parent = this.$parent while (parent.$options.componentName !== 'VForm') { parent = parent.$parent } return parent }, fieldError () { if (!this.prop) { return '' } const formError = this.form.formError return formError[this.prop] || '' } }, props: { prop: String, label: String } } </script>
FormItem 在 mounted 與 beforeDestroy 鉤子中還需要觸發(fā) Form 組件的一些自定義事件。
<script> export default { // ... methods: { dispatchEvent (eventName, params) { if (typeof this.form !== 'object' && !this.form.$emit) { console.error('FormItem必須在Form組件內(nèi)') return } this.form.$emit(eventName, params) } }, mounted () { if (this.prop) { this.dispatchEvent('form.addField', { prop: this.prop, el: this.$el }) } }, beforeDestroy () { if (this.prop) { this.dispatchEvent('form.removeField', { prop: this.prop }) } } } </script>
最后新建一個(gè) index.js 導(dǎo)出編寫好的組件。
import VForm from './Form.vue' import FormItem from './FormItem.vue' export { VForm, FormItem }
表單的校驗(yàn)函數(shù)是在 Form 組件中。通過$ref 可以訪問到 Form 組件,調(diào)用 validate 函數(shù),從而獲取到相應(yīng)的校驗(yàn)信息。
使用方法如下:
<template> <v-form :model="formData" :rules="rules" ref="form"> <form-item label="手機(jī)號(hào)" prop="tel"> <input type="tel" maxlength="11" v-model.trim="formData.tel"/> </form-item> <button @click="handleSubmit">保存</button> </v-form> </template> <script> import { VForm, FormItem } from './common/Form' export default { data () { return { formData: { tel: '' }, rules: { tel: [ {required: true, message: '您的手機(jī)號(hào)碼未輸入'}, {pattern: /^1[34578]\d{9}$/, message: '您的手機(jī)號(hào)碼輸入錯(cuò)誤'} ] } } }, methods: { handleSubmit () { this.$refs.form.validate(errs => { console.log(errs) }) } }, components: { VForm, FormItem } } </script>
關(guān)于使用async-validator怎么編寫一個(gè)Form組件就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。