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

首頁 > 編程 > JavaScript > 正文

vue表單驗證你真的會了嗎?vue表單驗證(form)validate

2019-11-19 11:52:03
字體:
來源:轉載
供稿:網友

前言

很久沒有寫文章了,學習了一下webpack,基礎的一些組件,今天帶來form表單驗證組件(element.iviewui)的一期教程(作為一個菜雞畢竟經歷眾多項目可以給一些新手一點提示 (QQ群技術討論)838293023備注(github進來的

github 技術文檔 技術文檔會持續更新

效果圖

 

1.原理解釋

考慮

我們看一下我們可以用form去整體觸發校驗也可以單個input來觸發form-item 進行校驗 童鞋們現在可能感覺還是沒懂,沒關系繼續往下看。

2.派發和廣播

為什么要用廣播和派發呢。通常我們和業務沒有關系的組件盡量不要使用vuex和bus(事件總線)。 下面我送上廣播和派發的代碼。我們在需要調用組件綁上 this.$on('event',res=>()) ,通過派發和廣播進行調用 $emit

  • 派發是向上查找且只調用1個
  • 廣播是向下查找調用多個
  • 注意⚠️所有的組件都要寫上name
  • 通過混合器 mixins 來使用
emitter.js/** * 遞歸使用 call 方式this指向 * @param componentName // 需要找的組件的名稱 * @param eventName // 事件名稱 * @param params // 需要傳遞的參數 */function broadcast(componentName, eventName, params) { // 循環子節點找到名稱一樣的子節點 否則 遞歸 當前子節點 this.$children.map(child=>{  if (componentName===child.$options.name) {   child.$emit.apply(child,[eventName].concat(params))  }else {   broadcast.apply(child,[componentName,eventName].concat(params))  } })}export default { methods: {  /**   * 派發 (向上查找) (一個)   * @param componentName // 需要找的組件的名稱   * @param eventName // 事件名稱   * @param params // 需要傳遞的參數   */  dispatch(componentName, eventName, params) {   let parent = this.$parent || this.$root;//$parent 找到最近的父節點 $root 根節點   let name = parent.$options.name; // 獲取當前組件實例的name   // 如果當前有節點 && 當前沒名稱 且 當前名稱等于需要傳進來的名稱的時候就去查找當前的節點   // 循環出當前名稱的一樣的組件實例   while (parent && (!name||name!==componentName)) {    parent = parent.$parent;    if (parent) {     name = parent.$options.name;    }   }   // 有節點表示當前找到了name一樣的實例   if (parent) {    parent.$emit.apply(parent,[eventName].concat(params))   }  },  /**   * 廣播 (向下查找) (廣播多個)   * @param componentName // 需要找的組件的名稱   * @param eventName // 事件名稱   * @param params // 需要傳遞的參數   */  broadcast(componentName, eventName, params) {   broadcast.call(this,componentName, eventName, params)  } }}

3.async-validator

不懂 async-validator 可以去官網看看 github

yarn add async-validator // 因為當前這個插件是需要打包到項目里的所以不能加-D

4.api設計

我們看一下下面 element 官網的圖`

form 有2個注入的字段 :rules 規則,和 :model 當前form的值會通過 model 的值和 rules 進行匹配來進行校驗.

form-item 有2個注入的字段 lableprop ( prop )是來和 form 進行匹配來獲取當前的 form-item 的值的

input 其實有當前的 @input 的方法。 v-model 就不解釋了

 

form

我們在 form 先開始注入當前所有的 form-item 實例(獲取)

created 會在生命周期開始的時候綁定和刪除當前實例的方法。通常綁定都在頁面dom開始前調用需要在 dom 加載完

provide 配合inject 使用讓子組件可以調用當前父組件的方法以及data

下面都寫了備注可以放心食用(經過測試當前是可以進行校驗的)

form.vue<template> <form>  <slot></slot> </form></template><script> export default {  name: "aiForm",  provide(){ // [不懂的可以看看](https://cn.vuejs.org/v2/api/#provide-inject)   return {    form: this   }  },  props: {   // 當前 form 的model   model: {    type: Object   },   // 驗證   rules: {    type: Object   }  },  data(){   return{    fields: [] // 儲存當前的 form-item的實例   }  },  created(){   // 存當前實例   let that =this;   this.$on('on-form-item-add',item=>{    if (item) {     that.fields.push(item)    }   });   // 刪除當前有的實例   this.$on('on-form-item-remove',item=>{    if (item.prop) {// 如果當前沒有prop的話表示當前不要進行刪除(因為沒有注入)     that.fields.splice(that.fields.indexOf(item),1)    }   })  },  methods:{   /**    * 清空    */   resetFields(){//添加resetFields方法使用的時候調用即可    /**     * 當前所有當form-item 進行賦值     */    this.fields.forEach(field => {     field.resetField();    });   },   /**    * 校驗 公開方法:全部校驗數據,支持 Promise    */   validate(callback){    return new Promise(resolve=>{     /**      * 當前所有當form-item 進行校驗      */     let valid = true; // 默認是通過     let count = 0; // 來匹配當前是否是全部檢查完     this.fields.forEach(field => {      // 每個實例都會有 validation 的校驗的方法      field.validation('',error=>{       // 只要有一個不符合那么當前的校驗就是未通過的       if (error) {         valid = false;       }       // 通過當前檢查完所有的form-item的時候才會調用       if (++count === this.fields.length) {        resolve(valid);// 方法使用then        if (typeof callback === 'function') {         callback(valid);// 直接調用注入的回調方法        }       }      });     });    })   }  } }</script>

5.form-item

  •  form-item比較復雜我們一個一個講
  • isRequired來判斷當前是否需要必填
  • validateState來判斷當前校驗的狀態
  • validateMessage當前的錯誤的值
  • inject: ['form'] 我們就可以通過this.from.xxx來調用父組件的事件以及值了
  • computed下的fieldValue可能在不停的變化所以我們通過計算屬性來使用
  • initialValue 默認的值我們在mounted的時候且當前需要進行校驗的時候(prop有的時候)會賦值
  • mixins: [Emitter]混合器就是里面的方法以及date都可以在當前調用使用頻繁的都可以放在混合器里面
  • 我們form-item 會傳入input的兩個方法blur和change(input原生使用的@input)通過form傳入的校驗rules里面的trigger來判斷
form-item.vue<template> <div>  <label :class="isRequired?'ai-form-item-label-required':''">{{label}}</label>  <div>   <slot></slot>   <div class="ai-form-item-message" v-if="validateState==='error'">{{validateMessage}}</div>  </div> </div></template><script> import Emitter from '../../mixins/emitter'; import schema from 'async-validator'; export default {  name: "aiFormItem",  mixins: [Emitter],  inject: ['form'],  props: {   label: {    type: String,    default: ''   },   prop:{    type: String   },  },  computed:{   fieldValue () {    return this.form.model[this.prop];   },  },  data(){   return {    initialValue: '', // 儲存默認值    isRequired: false, // 當前的是否有問題    validateState: '', // 是否校驗成功    validateMessage: '', // 校驗失敗文案   }  },  methods:{   /**    * 綁定事件 進行是否 required 校驗    */   setRules(){    let that = this;    let rules = this.getRules();//拿到父組件過濾后當前需要使用的規則    if (rules.length) {     // every 方法用于檢測數組所有元素是否都符合指定條件(通過函數提供)     // some 只要有一個符合就返回true     this.isRequired = rules.some(rule=>{      // 如果當前校驗規則中有必填項,則標記出來      return rule.required;     })    }    /**     * blur 事件     */    this.$on('on-form-blur',that.onFieldBlur);    /**     * change 事件     */    this.$on('on-form-change',that.onFieldChange)   },   /**    * 從 Form 的 rules 屬性中,獲取當前 FormItem 的校驗規則    */   getRules () {    let that = this;    let rules = that.form.rules;    rules = rules?rules[that.prop]:[];    return [].concat(rules||[])//這種寫法可以讓規則肯定是一個數組的形式   },   /**    * Blur 進行表單驗證    */   onFieldBlur(){    this.validation('blur')   },   /**    * change 進行表單驗證    */   onFieldChange(){    this.validation('change')   },   /**    * 只支持 blur 和 change,所以過濾出符合要求的 rule 規則    */   getFilteredRule (trigger) {    let rules = this.getRules();    // !res.trigger 沒有調用方式的時候默認就校驗的    // filter 過濾出當前需要的規則    return rules.filter(res=>!res.trigger || res.trigger.indexOf(trigger)!==-1)   },   /**    * 校驗數據    * @param trigger 校驗類型    * @param callback 回調函數    */   validation(trigger,callback=function () {}){    // blur 和 change 是否有當前方式的規則    let rules = this.getFilteredRule(trigger);    // 判斷當前是否有規則    if (!rules || rules.length === 0) {     return    }    // 設置狀態為校驗中    // async-validator的使用形式    this.validateState = 'validating';    var validator = new schema({[this.prop]: rules});    // firstFields: true 只會校驗一個    validator.validate({[this.prop]: this.fieldValue}, { firstFields: true },(errors, fields) => {     this.validateState = !errors ? 'success' : 'error';     this.validateMessage = errors ? errors[0].message : '';     callback(this.validateMessage);    });   },   /**    * 清空當前的 form-item    */   resetField(){    this.form.model[this.prop] = this.initialValue;   }  },  // 組件渲染時,將實例緩存在 Form 中  mounted(){   // 如果沒有傳入 prop,則無需校驗,也就無需緩存   if (this.prop) {    this.dispatch('aiForm','on-form-item-add', this);    // 設置初始值,以便在重置時恢復默認值    this.initialValue = this.fieldValue;    // 添加表單校驗    this.setRules()   }  },  // 組件銷毀前,將實例從 Form 的緩存中移除  beforeDestroy(){   this.dispatch('iForm', 'on-form-item-remove', this);  }, }</script><style scoped> <!--當前css--> .ai-form-item-label-required:before{  content: '*';  color: red; } .ai-form-item-message {  color: red; }</style>

5.input

  •  value 支持一個入參
  • 因為當前是一個 input 注入的參數是不能直接放到 input 里面使用的所以先賦值給了 defaultValue 然后用 watch 來不停給 defaultValue 賦值達到一個父組件修改后的一個綁定
<template> <input type="text"   @input="handleInput" // change   @blur="handleBlur"   :value="defaultValue" ></template><script> import Emitter from '../../mixins/emitter.js' export default {  name: "aiInput",  mixins: [Emitter],  props: {   value: {    type: String,    default: ''   }  },  data(){   return {    defaultValue: this.value   }   },  watch:{   value (val) {    this.defaultValue = val;   }  },  methods:{   /**   * change 事件   * @param event   */   handleInput(event){    // 當前model 賦值    this.defaultValue = event.target.value;    // vue 原生的方法 return 出去    this.$emit('input',event.target.value);    // 將當前的值發送到 aiFormItem 進行校驗    this.dispatch('aiFormItem','on-form-change',event.target.value)   },   /**   * blur 事件   * @param event   */   handleBlur(event){    // vue 原生的方法 return 出去    this.$emit('blur',event.target.value);    // 將當前的值發送到 aiFormItem 進行校驗    this.dispatch('aiFormItem','on-form-blur',event.target.value)   }  } }</script>

最后

最后給上一個當前可以的使用方式

<template> <div class="home"> <button @click="changeButton">測試</button> <ai-form ref="formItems" :model="formValidate" :rules="ruleValidate">  <ai-form-item label="用戶名" prop="name">  <ai-input v-model="formValidate.name"/>  </ai-form-item> </ai-form> </div></template><script> import AiForm from "../components/form/form"; import AiFormItem from "../components/form/form-item"; import AiInput from "../components/input/ai-input";export default { name: 'home', components: {AiInput, AiFormItem, AiForm},], data(){  return{   formValidate: {    name: '123z',    mail: ''   },   ruleValidate: {    name: [     { required: true, message: '用戶名不能為空', trigger: 'blur' },    ],   }  } }, methods:{  changeButton(){   this.$refs.formItems.resetFields() // 清空方法   this.$refs.formItems.validate() // 驗證方法    .then(res=>{     console.log(res)    })  } },}</script>

小結

可能現在小伙伴還是不懂。。俗話說;師傅領進門,修行在個人。代碼上的備注寫的也夠多了。

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 望城县| 瓮安县| 墨江| 万宁市| 玛沁县| 乌兰察布市| 保定市| 西宁市| 莆田市| 拉萨市| 星座| 延寿县| 额济纳旗| 克山县| 班戈县| 龙州县| 望城县| 绥德县| 什邡市| 木兰县| 福建省| 哈密市| 平和县| 三原县| 广宗县| 科技| 明水县| 昌黎县| 伊春市| 桐庐县| 济宁市| 志丹县| 汝州市| 太湖县| 仁化县| 密山市| 宜宾县| 合水县| 包头市| 东乌珠穆沁旗| 沂南县|