国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

使用async-validator編寫Form組件的方法

2019-11-19 14:33:17
字體:
來源:轉載
供稿:網友

前端開發中,表單的校驗一個很常見的功能,一些 ui 庫例如ant.design Element ui 都實現了有校驗功能的 Form 組件。async-validator 是一個可以對數據進行異步校驗的庫,ant.design 與 Element ui 的 Form 組件都使用了 async-validator。本文就簡單介紹一下 async-validator 的基本用法以及使用該庫實現一個簡單的有校驗功能的 Form 組件。

1. async-validator 的基本用法

async-validator 的功能是校驗數據是否合法,并且根據校驗規則給出提示信息。

下面演示一下 async-validator 的最基本用法。

import AsyncValidator from 'async-validator'// 校驗規則const descriptor = { username: [ {  required: true,  message: '請填寫用戶名' }, {  min: 3,  max: 10,  message: '用戶名長度為3-10' } ]}// 根據校驗規則構造一個 validatorconst validator = new AsyncValidator(descriptor)const data = { username: 'username'}validator.validate(model, (errors, fields) => { console.log(errors)})

當數據不符合校驗規則時,在 validator.validate 的回調函數中,就可以得到相應的錯誤信息。

當 async-validator 中常見的校驗規則無法滿足需求時,我們可以編寫自定義的校驗函數來校驗數據。一個簡單的校驗函數如下。

function validateData (rule, value, callback) { let err if (value === 'xxxx') {  err = '不符合規范' } callback(err)}const descriptor = { complex: [  {  validator: validateData  } ]}const validator = new AsyncValidator(descriptor)

async-validator 支持對數據異步校驗,所以在編寫自定義校驗函數時,不管校驗是否通過,校驗函數中的 callback 都要調用。

2. 編寫 Form 組件與 FormItem 組件

現在知道了 async-validator 的使用方法,如何將這個庫跟要編寫的 Form 組件結合起來呢。

實現思路

用一張圖描述一下實現思路。

Form 組件

Form 組件應該是一個容器,里面包含不定數量的 FormItem 或者其他元素。可以使用 Vue 內置的slot 組件來代表 Form 里面的內容。

Form 組件還需要知道包含了多少個需要校驗的 FormItem 組件。一般情況下,父子組件的通信 是通過在子組件上綁定事件實現的,但是這里使用 slot,無法監聽到子組件的事件。這里可以在 Form 組件上通過$on 監聽事件,FormItem 掛載或者銷毀前觸發 Form 組件的自定義事件即可。

按照這個思路,我們先編寫 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 來找 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 校驗規則不存在或者其值不是數組`)     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    // 讓錯誤信息的順序與表單組件的順序相同    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 組件就簡單很多,首先要向上找到包含它的 Form 組件。接下來就可以根據 formError 計算出對應的錯誤信息。

<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 鉤子中還需要觸發 Form 組件的一些自定義事件。

<script>export default { // ... methods: {  dispatchEvent (eventName, params) {   if (typeof this.form !== 'object' && !this.form.$emit) {    console.error('FormItem必須在Form組件內')    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>

最后新建一個 index.js 導出編寫好的組件。

import VForm from './Form.vue'import FormItem from './FormItem.vue'export { VForm, FormItem}

3. 使用方式

表單的校驗函數是在 Form 組件中。通過$ref 可以訪問到 Form 組件,調用 validate 函數,從而獲取到相應的校驗信息。

使用方法如下:

<template> <v-form :model="formData" :rules="rules" ref="form">  <form-item label="手機號" 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: '您的手機號碼未輸入'},      {pattern: /^1[34578]/d{9}$/, message: '您的手機號碼輸入錯誤'}     ]    }   }  },  methods: {   handleSubmit () {    this.$refs.form.validate(errs => {     console.log(errs)    })   }  },  components: {   VForm,   FormItem  } }</script>

完整的代碼點擊這里

4. 總結

本文簡單介紹了一下 async-validator 的用法,并實現了一個有校驗功能的 Form 組件。這里的實現的 Form 表單存在著很多的不足:(1) 僅僅是在提交表單時才去校驗。(2) FormItem 組件也應該根據校驗的結果調整 ui,給出相應的提示。所以,Form 組件更適合在交互較少的移動端使用。

大家可以根據這個實現思路,根據應用場景,編寫定制化更高的 Form 組件。

參考資料

async-validator
Element ui 的 Form組件
Element ui 的 Form 源碼

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 余干县| 石狮市| 建水县| 宁明县| 漾濞| 阆中市| 安溪县| 碌曲县| 平湖市| 罗江县| 定西市| 大埔县| 阿坝| 灵宝市| 铁岭县| 克东县| 海门市| 泉州市| 潼关县| 富顺县| 烟台市| 廊坊市| 雅江县| 涿州市| 修水县| 彰化市| 辽宁省| 扶余县| 西峡县| 韶关市| 凤山县| 丹巴县| 安远县| 棋牌| 女性| 东阳市| 丹江口市| 象山县| 西峡县| 宝鸡市| 临洮县|