vant表單驗證組件

 組件 vantForm.vue

<template>
  <div>
   <slot name="items"></slot>
  </div>
</template>
<script>
     /**
      * author:ronggang
      * email:[email protected]
      */
     export default {
         name: 'vant-form',
         data() {
             return {
                 rulesEles: []
             }
         },
         props: ['inputVail', 'rules'],
         mounted() {
             // 遞歸獲取所有帶有 rule 屬性的元素
             this.rulesEles = this.getRuleEle(this.$slots.items);
             // 處理 輸入監聽的校驗
             if (this.inputVail) this.eleSetInput();
         },
         methods: {
             // 遞歸獲取插槽內所有擁有 input 屬性的元素【內部方法】
             getRuleEle(eleObj) {
                 let self = this, childs = [];
                 if (!eleObj) return;
                 // 循環所有元素(兼容 對象和數組的情況)
                 for (let i in eleObj instanceof Array ? eleObj : [eleObj]) {
                     let ele = eleObj[i];
                     // 當前元素包含 rule 屬性,則收錄起來
                     if (ele.data && ele.data.attrs['rule']) {
                         ele.elm.getElementsByClassName('van-field__error-message')[0].style.display = 'none';
                         childs.push(ele);
                     }
                     // 當前元素存在子元素,則遞歸查詢
                     ele.children && childs.push.apply(childs, this.getRuleEle(ele.children));
                 }
                 return childs;
             },
             // 設置 需要校驗的屬性 的 input監聽 校驗 【內部方法】
             eleSetInput() {
                 let self = this;
                 try {
                     for (let i in self.rulesEles) {
                         (function (index) {
                             // 獲取元素下 input 元素(目前只針對 單個輸入框做處理)
                             let inputEle = self.rulesEles[index].elm.getElementsByTagName('input')[0];
                             inputEle.oninput = function () {
                                 // 輸入實時校驗
                                 self.handleVail(index);
                             }
                         })(i);
                     }
                 } catch (e) {
                     console.error('vail error:' + e);
                 }
             },
             // 檢驗元素的值是否滿足條件(參數:索引值 )【內部方法】
             handleVail(i) {
                 try {
                     let self = this, handleEle = self.rulesEles[i];
                     // 獲取元素下 input 元素(目前只針對 單個輸入框做處理)
                     let inputValue = handleEle.elm.getElementsByTagName('input')[0].value, vailFlag = true;
                     // 獲取設置的校驗規則
                     let ruleObj = self.rules ? self.rules[handleEle.data.attrs['rule']] : null;
                     if (!ruleObj) return vailFlag;
                     // 非空校驗
                     vailFlag = ruleObj.required ? !!inputValue : vailFlag;
                     // 正則校驗
                     vailFlag = ruleObj.regExp ? ruleObj.regExp.test(inputValue) && vailFlag : vailFlag;
                     // 用戶自定義校驗
                     vailFlag = typeof ruleObj.handleVailFun === 'function' ? ruleObj.handleVailFun(inputValue) && vailFlag : vailFlag;
                     console.log(handleEle);
                     // 獲取組件實例,修改錯誤信息(註釋的代碼可以實現效果,但是違反了子組件修改父組件的規則)
                     // handleEle.componentInstance.errorMessage = vailFlag?'':ruleObj.errorMessage;
                     //目前是通過控制元素顯示隱藏去實現錯誤信息的展示
                     if (!vailFlag) self.rulesEles[i].elm.getElementsByClassName('van-field__error-message')[0].style.display = 'block';
                     else self.rulesEles[i].elm.getElementsByClassName('van-field__error-message')[0].style.display = 'none';
                     return vailFlag;
                 } catch (e) {
                     console.error('vail error:' + e);
                 }
             },
             // 整體校驗【對外提供方法】
             allVail() {
                 let self = this, vailFlag = true;
                 for (let i in this.rulesEles) {
                     vailFlag = !self.handleVail(i) ? false : vailFlag && true;
                 }
                 return vailFlag;
             }
         }
     }
</script>
<style>
</style>

使用

<template>
  <div class="form-container">
    <van-nav-bar title="表單校驗擴展組件"   left-text="返回"   left-arrow
                 @click-left="back"  />
    <vantForm ref="vanForm" :rules="rules" inputVail="true">
      <template slot="items">
        <van-field error-message="請輸入正確的用戶名~"  rule="userName"
                   label="用戶名" placeholder="請輸入用戶名"  v-model="reqParam.userName"/>
        <van-field error-message="請輸入正確的手機號~"  rule="phone"
                   label="手機號碼" placeholder="請輸入手機號碼"  v-model="reqParam.phone"/>
        <van-field error-message="請輸入6~20位密碼~" rule="pwd"
                   type="password" label="密碼" placeholder="請輸入密碼"  v-model="reqParam.pwd"/>
        <van-field error-message="兩次輸入密碼不一致~"  rule="confirmPwd"
                   type="password" label="再次輸入" placeholder="再次輸入" v-model="reqParam.confirmPwd" />
      </template>
    </vantForm>
    <van-button class="submit-btn" type="primary" @click="submitForm">提交</van-button>
  </div>
</template>

<script>
import VantForm from '../components/vantForm';
// import { Toast } from 'vant';

export default {
  name: 'formVail',
  data() {
    return {
      reqParam: {
        userName: '',
        phone: '',
        pwd: '',
        confirmPwd: ''
      },
      rules: {
        'userName': {required: true},
        'phone': {regExp: /^(1\d{10})$/, required: true},
        'pwd': { regExp: /^(\w){6,20}$/, required: true},
        'confirmPwd': { required: true
          ,handleVailFun:val => { return val === this.reqParam.pwd; }
        }
      }
    }
  },
  created() {
  },
  methods: {
    back() {
      this.$router.back();
    },
    submitForm() {
      this.$refs['vanForm'].allVail()?Toast.success('校驗通過'): Toast.fail('提交失敗');
    }
  },
  components: {
    VantForm
  }
}
</script>

<style scoped  lang="less">
  .form-container{
    .submit-btn{
      width:100%;
    }
  }
</style>

效果預覽

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章