摘要:今天就來介紹一下如何利用的自定義指令來開發(fā)一個表單驗證插件的過程。按照這種方式就能夠使用自己開發(fā)的這個表單校驗插件。
這段時間在進行一個新項目的前期搭建,新項目框架采用vue-cli3和typescirpt搭建。因為項目比較輕量,所以基本沒有使用額外的ui組件,有時候我們需要的一些基礎組件我就直接自己開發(fā)了。今天就來介紹一下如何利用vue的自定義指令directive來開發(fā)一個表單驗證插件的過程。
1.vue插件開發(fā)關于vue的插件開發(fā),官方文檔里有很清晰的說明,詳情可以去閱讀開發(fā)文檔。我自己開發(fā)的表單驗證插件validate.ts和loading,messageBox插件都是利用了這種方式。今天先來看表單驗證插件的開發(fā)。
vue全局指令
// myPlugin.js
export default {
install: (Vue, options) => {
// 注冊一個my-directive指令
Vue.directive("my-directive", {
bind(el, binding, vnode, oldVnode) {
// 邏輯
}
...
})
}
}
// main.js
import Vue from "vue";
import myPlugin from "myPlugin";
Vue.use(myPlugin);
上面是注冊一個vue指令插件的寫法。值得注意的是注冊自定義指令的時候,bind()函數(shù)為指令的鉤子函數(shù),其中的參數(shù)el表示指令綁定的元素,可以直接操作DOM。binding表示一個對象,包括指令名稱,綁定值等信息。vnode和oldVnode表示Vue編譯生成的虛擬節(jié)點。
我們通過注冊一個全局指令v-validateParams指令,綁定到輸入表單的input標簽上來校驗當前輸入值是否符合要求。
2.v-validateParams指令最開始我參考了網(wǎng)上的一些代碼。基礎的實現(xiàn)如下:
整體框架
import Vue from "vue"
export default {
install: (Vue, options) => {
// 注冊一個全局自定義指令 `v-validateParams`
Vue.directive("validateParams", {
// 當被綁定的元素插入到 DOM 中時
inserted: function (el, binding, vNode) {
// 給指令綁定的Dom元素添加事件監(jiān)聽,監(jiān)測輸入框失焦事件
// 每次當表單中的輸入框失焦時執(zhí)行函數(shù)
el.addEventListener("blur", function (event) {
// 1.首先重置所有錯誤提示
// 2.獲取自定義指令中傳入的校驗規(guī)則參數(shù)和表單輸入的值
// 3.依次判斷當前輸入的值是否符合校驗規(guī)則
})
}
})
// 注冊一個全局自定義指令 `v-validateSubmit`,這個指令綁定到表單的提交button上
Vue.directive("validateSubmit", {
// 當被綁定的元素插入到 DOM 中時
inserted: function (el, binding, vNode) {
// 給提交button添加事件監(jiān)聽
el.addEventListener("click", function (event) {
// 獲取當前組件內(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);
}
// 獲取當前組件下的所有錯誤提示元素
let errorInputs = vNode.context.$el.getElementsByClassName("input-error");
// 如果組件中沒有錯誤提示元素,則執(zhí)行當前組件實例中的submit()函數(shù)
if(errorInputs.length === 0){
vNode.context.submit();
}
})
}
})
}
}
這里需要著重說明一下validateSubmit指令,這個指令綁定到提交按鈕上,在點擊的時候執(zhí)行校驗,校驗通過之后執(zhí)行提交操作。但是這里的實現(xiàn)方式不是特別友好:
1.需要獲取當前組件中的所有input元素,給他們綁定并執(zhí)行blur事件,以此來執(zhí)行validateParams指令中的校驗邏輯。
2.需要獲取當前組件中的所有錯誤提示元素,如果他們存在就不能執(zhí)行提交操作。
3.當組件內(nèi)不含任何錯誤提示元素時,就表示校驗通過,執(zhí)行當前組件內(nèi)的submit函數(shù),所以每個表單組件的提交函數(shù)都只能命名為submit
然后我們再看下指令validateParams,該指令需要綁定到表單input元素上,并把校驗規(guī)則當作參數(shù)寫入。當該input元素失焦時,會執(zhí)行指令中給當前元素綁定的事件中的邏輯。這些邏輯分為三個步驟,我已經(jīng)寫在注釋里了,現(xiàn)在我們來看下具體實現(xiàn)。
重置所有錯誤提示
/**
* 重置當前節(jié)點樣式
* @param el: HTMLElement,傳入當前綁定的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);
}
}
};
獲取自定義指令中傳入的校驗規(guī)則參數(shù)和表單輸入的值
// binding.value是傳入自定義指令的參數(shù),以數(shù)組的形式
for (const rule of binding.value) {
// 分別獲取到自己定義的校驗規(guī)則并執(zhí)行
const { min, max, message, required, pattern } = rule;
if ( min && InputEl.value.length < min ) {
// 如果不符合校驗,執(zhí)行報錯函數(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;
}
}
校驗不符合,執(zhí)行報錯函數(shù)
/**
* 執(zhí)行錯誤提示函數(shù),用input-error 類名和含有錯誤信息的p元素表示未通過校驗
* @param el: HTMLElement,傳入當前綁定的input元素
* @param errorMsg: string,傳入錯誤提示信息
*/
const validateError = (el: HTMLElement, errorMsg: string) => {
if (Array.prototype.includes.call(el.classList, "input-error")) {
//如果當前組件里已經(jīng)有了錯誤提示信息,什么也不做
return;
} else {
const errorNode = document.createElement("p");
errorNode.className = "error-tips";
errorNode.textContent = errorMsg;
if (el.parentNode) {
// 在當前input 元素后追加一個p元素,內(nèi)容為錯誤提示
el.parentNode.appendChild(errorNode);
}
// 在當前input 元素上添加一個input-error類名
el.className += " input-error";
}
};
現(xiàn)在我就把自己實現(xiàn)的這個表單校驗插件大致說完了,下面我們看下具體使用。
3.自定義校驗指令v-validateParams使用首先新建校驗規(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
通過這個例子我們可以看到,使用時需要將校驗規(guī)則引入并賦給vue實例中的數(shù)據(jù)。然后在模板中,需要給input標簽添加v-check類名,再使用v-validateParams指令,并傳入?yún)?shù)。提交按鈕需要調(diào)用v-checkSubmit指令。按照這種方式就能夠使用自己開發(fā)的這個表單校驗插件。
4. 當前方式存在的問題雖然表單校驗可以使用了,但是存在一些顯而易見的問題:
1.js和html耦合度較高,插件還需要獲取dom元素,組件的html模板中還需要添加指定的類名。
2.在vue中使用dom操作,不符合vue的設計思路,實現(xiàn)方式也不優(yōu)雅。
3.校驗規(guī)則的校驗邏輯在指令定義時寫定了,添加或刪除都需要改動插件代碼。
4.提交指令根據(jù)當前組件內(nèi)的是否含有特定dom來判斷當前校驗狀態(tài),且執(zhí)行提交的函數(shù)名稱也在指令邏輯中寫定了。
我根據(jù)現(xiàn)有一個demo結(jié)合著自己的需求來實現(xiàn)的這個表單校驗插件,開發(fā)的過程中我已經(jīng)知道這么寫問題很多,甚至不能稱之為一個合格的插件。同時也清楚的認識到自己的javascript水平還很初級,需要很大進步。
當前開發(fā)的表單插件的主要問題在于如何將插件中的校驗狀態(tài)返回到組件內(nèi)。我們可以在插件內(nèi)維護一個事件處理函數(shù),將校驗規(guī)則傳入并校驗,再將校驗結(jié)果直接傳給組件內(nèi)。這樣就可以避免大量的dom操作。之后我需要盡快對這個插件進行更科學合理的重構(gòu)。
參考文章vue插件
vue自定義指令
vue使用自定義指令實現(xiàn)表單校驗
重構(gòu):從 0.1 構(gòu)建一個 Vue 表單驗證插件
va.js——Vue 表單驗證插件的寫作過程
原文鏈接:tech.gtxlab.com/vue-validat…
作者簡介: 宮晨光,人和未來大數(shù)據(jù)前端工程師。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/7269.html
摘要:寫一個表單驗證插件需求目標簡單易用可擴展如何簡單開發(fā)者要做的寫了一個表單,指定一個,指定其驗證規(guī)則。調(diào)用提交表單方法,可以獲取驗證成功后的數(shù)據(jù)。 寫一個vue表單驗證插件(vue-validate-easy) 需求 目標:簡單易用可擴展 如何簡單 開發(fā)者要做的 寫了一個表單,指定一個name,指定其驗證規(guī)則。 調(diào)用提交表單方法,可以獲取驗證成功后的數(shù)據(jù)。 調(diào)用重置表單方法重置表單 自...
摘要:寫一個表單驗證插件需求目標簡單易用可擴展如何簡單開發(fā)者要做的寫了一個表單,指定一個,指定其驗證規(guī)則。調(diào)用提交表單方法,可以獲取驗證成功后的數(shù)據(jù)。 寫一個vue表單驗證插件(vue-validate-easy) 需求 目標:簡單易用可擴展 如何簡單 開發(fā)者要做的 寫了一個表單,指定一個name,指定其驗證規(guī)則。 調(diào)用提交表單方法,可以獲取驗證成功后的數(shù)據(jù)。 調(diào)用重置表單方法重置表單 自...
摘要:寫一個表單驗證插件需求目標簡單易用可擴展如何簡單開發(fā)者要做的寫了一個表單,指定一個,指定其驗證規(guī)則。調(diào)用提交表單方法,可以獲取驗證成功后的數(shù)據(jù)。 寫一個vue表單驗證插件(vue-validate-easy) 需求 目標:簡單易用可擴展 如何簡單 開發(fā)者要做的 寫了一個表單,指定一個name,指定其驗證規(guī)則。 調(diào)用提交表單方法,可以獲取驗證成功后的數(shù)據(jù)。 調(diào)用重置表單方法重置表單 自...
摘要:示例電話電話錯誤信息指示指令對應的表單控件的驗證結(jié)果。其主要是根據(jù)驗證的結(jié)果進行的值的變換。如果為空值則默認把所有帶有驗證的空間作為需要驗證對象。 cddv vue.js 表單驗證插件使用說明 版本:1.0.8-6 獲取 github:這里 npm安裝 npm i vue-cdd-validator --save yarn安裝 yarn add vue-cdd-validator 安裝...
摘要:一表單驗證模塊的構(gòu)成任何表單驗證模塊都是由配置校驗報錯取值這幾部分構(gòu)成的。其實我是想寫個指令來完成表單驗證的事的。當然表單驗證這種是高度定制化的。 前言 前段時間,老大搭好了Vue的開發(fā)環(huán)境,于是我們愉快地從JQ來到了Vue。這中間做的時候,在表單驗證上做的不開心,看到vue的插件章節(jié),感覺自己也能寫一個,因此就自己開始寫了一個表單驗證插件va.js。 當然為什么不找個插件呢? vu...
閱讀 3679·2023-04-26 02:07
閱讀 3181·2021-09-22 15:55
閱讀 2549·2021-07-26 23:38
閱讀 3130·2019-08-29 15:16
閱讀 2020·2019-08-29 11:16
閱讀 1762·2019-08-29 11:00
閱讀 3602·2019-08-26 18:36
閱讀 3174·2019-08-26 13:32