欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用vue自定義指令開發(fā)表單驗(yàn)證插件validate.js

 更新時(shí)間:2019年05月23日 16:08:59   作者:genetalks_大數(shù)據(jù)  
今天就來介紹一下如何利用vue的自定義指令directive來開發(fā)一個(gè)表單驗(yàn)證插件的過程,需要的朋友可以參考下

這段時(shí)間在進(jìn)行一個(gè)新項(xiàng)目的前期搭建,新項(xiàng)目框架采用vue-cli3和typescirpt搭建。因?yàn)轫?xiàng)目比較輕量,所以基本沒有使用額外的ui組件,有時(shí)候我們需要的一些基礎(chǔ)組件我就直接自己開發(fā)了。今天就來介紹一下如何利用vue的自定義指令directive來開發(fā)一個(gè)表單驗(yàn)證插件的過程。

1.vue插件開發(fā)

關(guān)于vue的插件開發(fā),官方文檔里有很清晰的說明,詳情可以去閱讀開發(fā)文檔。我自己開發(fā)的表單驗(yàn)證插件validate.ts和loading,messageBox插件都是利用了這種方式。今天先來看表單驗(yàn)證插件的開發(fā)。

vue全局指令

// myPlugin.js
export default {
 install: (Vue, options) => {
 // 注冊一個(gè)my-directive指令
 Vue.directive('my-directive', {
  bind(el, binding, vnode, oldVnode) {
  // 邏輯
  }
  ...
 })
 }
}
// main.js
import Vue from 'vue';
import myPlugin from 'myPlugin';
Vue.use(myPlugin);

上面是注冊一個(gè)vue指令插件的寫法。值得注意的是注冊自定義指令的時(shí)候,bind()函數(shù)為指令的鉤子函數(shù),其中的參數(shù)el表示指令綁定的元素,可以直接操作DOM。binding表示一個(gè)對象,包括指令名稱,綁定值等信息。vnode和oldVnode表示Vue編譯生成的虛擬節(jié)點(diǎn)。

我們通過注冊一個(gè)全局指令v-validateParams指令,綁定到輸入表單的input標(biāo)簽上來校驗(yàn)當(dāng)前輸入值是否符合要求。

2.v-validateParams指令

最開始我參考了網(wǎng)上的一些代碼。基礎(chǔ)的實(shí)現(xiàn)如下:

整體框架

import Vue from 'vue'
export default {
 install: (Vue, options) => {
 // 注冊一個(gè)全局自定義指令 `v-validateParams`
 Vue.directive('validateParams', {
  // 當(dāng)被綁定的元素插入到 DOM 中時(shí)
  inserted: function (el, binding, vNode) {
  // 給指令綁定的Dom元素添加事件監(jiān)聽,監(jiān)測輸入框失焦事件
  // 每次當(dāng)表單中的輸入框失焦時(shí)執(zhí)行函數(shù)
  el.addEventListener('blur', function (event) {
   // 1.首先重置所有錯(cuò)誤提示
   // 2.獲取自定義指令中傳入的校驗(yàn)規(guī)則參數(shù)和表單輸入的值
   // 3.依次判斷當(dāng)前輸入的值是否符合校驗(yàn)規(guī)則
  })
  }
 })
 // 注冊一個(gè)全局自定義指令 `v-validateSubmit`,這個(gè)指令綁定到表單的提交button上
 Vue.directive('validateSubmit', {
  // 當(dāng)被綁定的元素插入到 DOM 中時(shí)
  inserted: function (el, binding, vNode) {
  // 給提交button添加事件監(jiān)聽
  el.addEventListener('click', function (event) {
   // 獲取當(dāng)前組件內(nèi)所有含有v-check類名的元素
   let elements = vNode.context.$el.getElementsByClassName('v-check')
   var evObj = vNode.context.$el.createEvent('Event')
   evObj.initEvent('blur', true, true)
   for (let element of elements) {
   // 給所有v-check元素綁定blur事件
   element.dispatchEvent(evObj);
   }
   // 獲取當(dāng)前組件下的所有錯(cuò)誤提示元素
   let errorInputs = vNode.context.$el.getElementsByClassName('input-error');
   // 如果組件中沒有錯(cuò)誤提示元素,則執(zhí)行當(dāng)前組件實(shí)例中的submit()函數(shù)
   if(errorInputs.length === 0){
   vNode.context.submit();
   }
  })
  }
 })
 }
}

這里需要著重說明一下 validateSubmit 指令,這個(gè)指令綁定到提交按鈕上,在點(diǎn)擊的時(shí)候執(zhí)行校驗(yàn),校驗(yàn)通過之后執(zhí)行提交操作。但是這里的實(shí)現(xiàn)方式不是特別友好:

1.需要獲取當(dāng)前組件中的所有input元素,給他們綁定并執(zhí)行 blur 事件,以此來執(zhí)行 validateParams 指令中的校驗(yàn)邏輯。

2.需要獲取當(dāng)前組件中的所有錯(cuò)誤提示元素,如果他們存在就不能執(zhí)行提交操作。

3.當(dāng)組件內(nèi)不含任何錯(cuò)誤提示元素時(shí),就表示校驗(yàn)通過,執(zhí)行當(dāng)前組件內(nèi)的 submit 函數(shù),所以每個(gè)表單組件的提交函數(shù)都只能命名為 submit

然后我們再看下指令 validateParams ,該指令需要綁定到表單 input 元素上,并把校驗(yàn)規(guī)則當(dāng)作參數(shù)寫入。當(dāng)該input元素失焦時(shí),會執(zhí)行指令中給當(dāng)前元素綁定的事件中的邏輯。這些邏輯分為三個(gè)步驟,我已經(jīng)寫在注釋里了,現(xiàn)在我們來看下具體實(shí)現(xiàn)。

重置所有錯(cuò)誤提示

/**
 * 重置當(dāng)前節(jié)點(diǎn)樣式
 * @param el: HTMLElement,傳入當(dāng)前綁定的input元素
 */
const resetError = (el: HTMLElement) => {
 el.className = el.className.replace('input-error', '').trim();
 if ( el.parentNode ) {
 const ErrorNode = el.parentNode.querySelector('.error-tips');
 if (ErrorNode) {
  el.parentNode.removeChild(ErrorNode);
 }
 }
};

獲取自定義指令中傳入的校驗(yàn)規(guī)則參數(shù)和表單輸入的值

// binding.value是傳入自定義指令的參數(shù),以數(shù)組的形式
for (const rule of binding.value) {
 // 分別獲取到自己定義的校驗(yàn)規(guī)則并執(zhí)行
 const { min, max, message, required, pattern } = rule;
 if ( min && InputEl.value.length < min ) {
 // 如果不符合校驗(yàn),執(zhí)行報(bào)錯(cuò)函數(shù)
 validateError(InputEl, message);
 break;
 }
 if ( max && InputEl.value.length > max ) {
 validateError(InputEl, message);
 break;
 }
 if ( !!required && !InputEl.value ) {
 validateError(InputEl, message);
 break;
 }
 if ( pattern && !pattern.test(InputEl.value) ) {
 validateError(InputEl, message);
 break;
 }
 if ( rule && typeof rule === 'function' ) {
 rule(vNode.context, InputEl.value, validateError, InputEl);
 break;
 }
}

校驗(yàn)不符合,執(zhí)行報(bào)錯(cuò)函數(shù)

/**
 * 執(zhí)行錯(cuò)誤提示函數(shù),用input-error 類名和含有錯(cuò)誤信息的p元素表示未通過校驗(yàn)
 * @param el: HTMLElement,傳入當(dāng)前綁定的input元素
 * @param errorMsg: string,傳入錯(cuò)誤提示信息
 */
const validateError = (el: HTMLElement, errorMsg: string) => {
 if (Array.prototype.includes.call(el.classList, 'input-error')) {
 //如果當(dāng)前組件里已經(jīng)有了錯(cuò)誤提示信息,什么也不做
 return;
 } else {
 const errorNode = document.createElement('p');
 errorNode.className = 'error-tips';
 errorNode.textContent = errorMsg;
 if (el.parentNode) {
  // 在當(dāng)前input 元素后追加一個(gè)p元素,內(nèi)容為錯(cuò)誤提示
  el.parentNode.appendChild(errorNode);
 }
 // 在當(dāng)前input 元素上添加一個(gè)input-error類名
 el.className += ' input-error';
 }
};

現(xiàn)在我就把自己實(shí)現(xiàn)的這個(gè)表單校驗(yàn)插件大致說完了,下面我們看下具體使用。

3.自定義校驗(yàn)指令v-validateParams使用

首先新建校驗(yàn)規(guī)則文件:

// rules.ts
export const required = (message) => ({
 message,
 required: true
});
export const min = (message, length=3) => ({
 message,
 min: length
})
export const max = (message, length=15) => ({
 message,
 max: length
})
export const pattern = (message, reg) => ({
 message,
 pattern: reg
})
// form.vue
<template>
 <div>
 <div class="form-item">
  <label for="userEmail">用戶名:</label>
  <input id="userEmail" class='v-check' type="text" v-model="userName"
  v-validateParams="[inputNameRequired, inputNameMin, inputNameMax, inputNamePattern]">
 </div>
 <button class="btn" v-if="show" type="success" v-checkSubmit>確認(rèn)</button>
 </div>
</template>
<script lang='ts'>
import { Component, Vue, Prop } from 'vue-property-decorator';
import { max, min, required, name, pattern} from 'rules';

@Component({
 components: {},
})
export default class Auth extends Vue {
 private show: boolean = true;
 private userName: string = '';
 private inputNameMax = max('請不要超過20個(gè)字符');
 private inputNameMin = min('請不要小于3個(gè)字符');
 private inputNameRequired = required('請輸入用戶名');
 private inputNamePattern = pattern('請輸入符合要求的用戶名', /^[a-zA-Z0-9_-]{4,16}$/);
 private submit() {
 alert('通過校驗(yàn)');
 }
}
</script>

通過這個(gè)例子我們可以看到,使用時(shí)需要將校驗(yàn)規(guī)則引入并賦給vue實(shí)例中的數(shù)據(jù)。然后在模板中,需要給 input 標(biāo)簽添加 v-check 類名,再使用 v-validateParams 指令,并傳入?yún)?shù)。提交按鈕需要調(diào)用 v-checkSubmit 指令。按照這種方式就能夠使用自己開發(fā)的這個(gè)表單校驗(yàn)插件。

3. 當(dāng)前方式存在的問題

雖然表單校驗(yàn)可以使用了,但是存在一些顯而易見的問題:

1.js和html耦合度較高,插件還需要獲取dom元素,組件的html模板中還需要添加指定的類名。

2.在vue中使用dom操作,不符合vue的設(shè)計(jì)思路,實(shí)現(xiàn)方式也不優(yōu)雅。

3.校驗(yàn)規(guī)則的校驗(yàn)邏輯在指令定義時(shí)寫定了,添加或刪除都需要改動插件代碼。

4.提交指令根據(jù)當(dāng)前組件內(nèi)的是否含有特定dom來判斷當(dāng)前校驗(yàn)狀態(tài),且執(zhí)行提交的函數(shù)名稱也在指令邏輯中寫定了。

我根據(jù)現(xiàn)有一個(gè)demo結(jié)合著自己的需求來實(shí)現(xiàn)的這個(gè)表單校驗(yàn)插件,開發(fā)的過程中我已經(jīng)知道這么寫問題很多,甚至不能稱之為一個(gè)合格的插件。同時(shí)也清楚的認(rèn)識到自己的javascript水平還很初級,需要很大進(jìn)步。

當(dāng)前開發(fā)的表單插件的主要問題在于如何將插件中的校驗(yàn)狀態(tài)返回到組件內(nèi)。我們可以在插件內(nèi)維護(hù)一個(gè)事件處理函數(shù),將校驗(yàn)規(guī)則傳入并校驗(yàn),再將校驗(yàn)結(jié)果直接傳給組件內(nèi)。這樣就可以避免大量的dom操作。之后我需要盡快對這個(gè)插件進(jìn)行更科學(xué)合理的重構(gòu)。

總結(jié)

以上所述是小編給大家介紹的使用vue自定義指令開發(fā)表單驗(yàn)證插件validate.js,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時(shí)回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

  • Vue循環(huán)中多個(gè)input綁定指定v-model實(shí)例

    Vue循環(huán)中多個(gè)input綁定指定v-model實(shí)例

    這篇文章主要介紹了Vue循環(huán)中多個(gè)input綁定指定v-model實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • 解決vue項(xiàng)目中type=”file“ change事件只執(zhí)行一次的問題

    解決vue項(xiàng)目中type=”file“ change事件只執(zhí)行一次的問題

    這篇文章主要介紹了vue項(xiàng)目中解決type=”file“ change事件只執(zhí)行一次的問題,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2018-05-05
  • Vue+Echarts繪制餅圖的示例詳解

    Vue+Echarts繪制餅圖的示例詳解

    這篇文章主要為大家詳細(xì)介紹了如何利用Vue和Echarts實(shí)現(xiàn)繪制餅圖,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-03-03
  • vue3+ts+elementPLus實(shí)現(xiàn)v-preview指令

    vue3+ts+elementPLus實(shí)現(xiàn)v-preview指令

    本文主要介紹了vue3+ts+elementPLus實(shí)現(xiàn)v-preview指令,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • vue全家桶-vuex深入講解

    vue全家桶-vuex深入講解

    這篇文章主要介紹了vue全家桶-vuex深入講解,文章內(nèi)容詳細(xì),簡單易懂,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2023-01-01
  • Vue this.$router.push(參數(shù))實(shí)現(xiàn)頁面跳轉(zhuǎn)操作

    Vue this.$router.push(參數(shù))實(shí)現(xiàn)頁面跳轉(zhuǎn)操作

    這篇文章主要介紹了Vue this.$router.push(參數(shù))實(shí)現(xiàn)頁面跳轉(zhuǎn)操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • Vue中的計(jì)算屬性computed傳參方式

    Vue中的計(jì)算屬性computed傳參方式

    這篇文章主要介紹了Vue中的計(jì)算屬性computed傳參方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Vue路由之JWT身份認(rèn)證的實(shí)現(xiàn)方法

    Vue路由之JWT身份認(rèn)證的實(shí)現(xiàn)方法

    這篇文章主要介紹了Vue路由之JWT身份認(rèn)證的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Vue3自定義打印實(shí)現(xiàn)原理詳解

    Vue3自定義打印實(shí)現(xiàn)原理詳解

    近接觸到了一個(gè) Vue3 的打印需求,我發(fā)現(xiàn)自己雖然從事前端開發(fā)已有多年,但對如何實(shí)現(xiàn)自定義打印還沒有深入研究,一般都是找現(xiàn)成的庫來解決問題,借這次的機(jī)會研究了一下如何實(shí)現(xiàn)自定義打印,需要的朋友可以參考下
    2024-07-07
  • vue中g(shù)et方法\post方法如何傳遞數(shù)組參數(shù)詳解

    vue中g(shù)et方法\post方法如何傳遞數(shù)組參數(shù)詳解

    在前后端交互的時(shí)候,有時(shí)候需要通過get或者delete傳遞一個(gè)數(shù)組給后臺,下面下面這篇文章主要給大家介紹了關(guān)于vue中g(shù)et方法\post方法如何傳遞數(shù)組參數(shù),文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-03-03

最新評論