原文:https://dev.to/ratracegrad/creating-custom-directives-in-vue-58hh
翻譯:心上有楊
指令是帶有 v- 前綴的特殊屬性。指令的作用是當表達值發生變化時將副作用反應性地應用於 DOM。Vue.js 提供了大量的指令供你使用。你可能已經使用過 v-if、v-repeat、v-model 和 v-show 等指令。
在這篇文章中,我將解釋指令的各個部分以及可以使用的內容。然后我將向你展示如何創建自定義指令以便您可以將編程需求直接應用於DOM元素。因此讓我們開始討論指令中包含的內容吧。
指令名
最基本的自定義指令只有一個名稱。它不接受任何參數也沒有任何修飾符。如果不傳遞值,這將不是很靈活,但是你仍舊可以擁有DOM元素的一些功能。您可能熟悉的一個示例是v-else指令。 以下是我們即將創建的自定義指令的示例:
<app-navigation v-sticky></app-navigation>
傳值給指令
你可以將值傳給自定義指令。這是一個例子:
<div v-if="isVisible">Show this</div>
在這個例子中,如果屬性值為 true 的話則顯示 v-if 指令。 我們知道這是在尋找屬性值,因為它包含在引號中。相反,如果我們想將一個字符串當成值傳給指令,你可以執行以下操作:
<div v-color="'red'">Show this</div>
參數
自定義指令可以在指令名稱后面加上冒號表示參數。這是一個例子:
<app-navigation v-sticky:bottom></app-navigation>
在上面的例子中,自定義指令的名稱是 sticky,參數是 bottom。
指令只可以攜帶一個參數。
修飾符
修飾符是由點表示的特殊后綴,表示指令應該以某種特殊方式被綁定。修飾符控制指令的行為。以下是我們創建自定義指令的實例:
<span v-format.underline>guide</span>
在上面的例子中,.underline修飾符告訴 v-format 指令對文本應用下划線。
你可以使用鏈接指令在指令上使用多個修飾符,這是一個例子:
<span v-format.bold.highlight.underline>guide</span>
在上面的例子中,文本將會加粗、高亮、下划線顯示。
創建自定義指令
現在你了解了 Vue.js 中指令的基礎知識。 除了核心中提供的默認指令集外,Vue 還允許您注冊自己的自定義指令。 讓我們創建自己的自定義指令吧。
在它的基礎上,我們可以使用 Vue.directive 創建一個全局指令並為其命名。 以下是使用名稱 sticky 創建自定義指令的示例。
Vue.directive('sticky');
當我們想在DOM元素上使用這個自定義指令時:
<app-navigation v-sticky></app-navigation>
現在我們已經創建了我們的第一個自定義指令,現在我們需要在它后面創建代碼。在創建之前,我們需要了解 Vue 為我們在自定義指令中提供的值。
指令鈎子
Vue 為自定義指令提供了一系列鈎子。 每個鈎子都有一些參數選項。 以下是可用的鈎子:
bind - 當指令附加到元素時會發生的情況。
inserted - 一旦元素插入父 DOM 就會發生這種情況
update - 這在元素更新時發生,但子項尚未更新
componentUpdated - 一旦更新了組件和子組件,就會發生這種情況
unbind - 刪除指令后會發生這種情況
其中每個都有 el,binding 和 vnode 參數可供他們使用。 這些論點是:
el - 綁定所依賴的元素
binding - 一個包含傳遞給鈎子的參數的對象。 有許多可用的參數,包括 name,value,oldValue,expression,arg 和 modifiers。
vnode - 允許您根據需要直接引用虛擬 DOM 中的節點。
binding 和 vnode 都應該被視為只讀。
update 和 componentUpdated 都公開了一個名為 oldvnode 的附加參數。 oldvnode 參數用於區分傳遞的舊值和較新的值。
bind 和 update 是五個中最有用的。
Demo #1 v-sticky
讓我們編寫我們想要的 v-sticky 指令所具有的行為。 當該指令應用於DOM元素時,我們希望在屏幕上定位該元素。 這是我們的 v-sticky 指令的自定義代碼:
Vue.directive('sticky', function(el, binding, vnode) { el.style.position = 'fixed'; } ));
讓我們分解一下代碼中的內容。 我正在使用 Vue.directive 創建一個名為 “sticky” 的新全局指令。 在名稱之后,我們有一個函數,它具有我們之前討論過的三個參數。 在函數中,我正在使用指令已經應用的元素並獲得它的樣式然后它的位置。 我把它設置為 fixed。
稍后我們將修改器應用於此自定義指令。
Demo #2 v-orange
我們將創建的下一個自定義指令是v-orange。 該指令將文本顏色設置為橙色。 以下是此指令的代碼:
Vue.directive("orange", function(el, binding, vnode) { el.style.color = "orange"; });
我們可以將此指令應用於 HelloWorld 組件中顯示的消息。 應用后,歡迎消息現在為橙色。
Demo #3 v-color
之前的指令不是很通用。 如果您希望文本為藍色而不是橙色,則必須編寫另一個自定義指令。 我們將創建一個名為 v-color 的新自定義指令。 此自定義指令將采用將傳遞給它的值。 此值是我們要應用於歡迎消息的顏色。
前面我提到綁定是一個對象,它包含傳遞給指令的參數。 該對象中包含的一個項是傳入的值。我們將在代碼中使用它來將文本設置為該值。
Vue.directive("color", function(el, binding, vnode) { el.style.color = binding.value; });
現在我們的指令更加靈活。 您可以傳入任何眾所周知的顏色字符串,如“紅色”或“藍色”,並傳入有效的十六進制顏色,如#ffff00。 這是我們新的 v-color 指令的圖像被應用三次。 第一次顏色為紅色,第二次顏色為藍色,最后一次顏色為黃色,使用#ffff00的十六進制代碼。
Demo #4 帶參數的v-sticky
您可以為自定義指令提供參數。 我們將修改我們之前創建的 v-sticky 代碼以接受參數。 大多數網站的屏幕頂部都有導航,屏幕底部有一個頁腳。
我們將使用該參數告訴我們導航是否應固定在屏幕的頂部或底部。 綁定對象將包含一個名為 arg 的值,該值包含我們傳遞給自定義指令的參數。
為了簡化操作,如果沒有參數傳遞給指令,我假設導航應該固定在屏幕的頂部。 如果我收到一個參數,那么導航將固定在屏幕的底部。
為了區分頂部和底部導航,我在頂部導航中添加了灰色的背景顏色,在底部導航中添加了棕褐色。 這是代碼:
Vue.directive("sticky", function(el, binding, vnode) { const loc = binding.arg === "bottom" ? "bottom" : "top"; el.style.position = "fixed"; el.style[loc] = 0; if (loc === "bottom") { el.style.background = "burlywood"; } else { el.style.background = "#7e7e7e"; } });
將我們更新的自定義指令應用於導航和頁腳后,它看起來像這樣。
Demo #5 v-format 使用修飾符
您可以根據需要向自定義指令添加任意數量的修飾符。 我們將創建一個名為 format 的新自定義指令。 此自定義指令將接受以下一個或多個修飾符:
underline
bold
highlight
綁定參數是一個對象。 該對象包含自定義指令的所有修飾符。 綁定上的修飾符實際上也是一個對象。 該對象將包含已應用的每個修改器的鍵。 我們將使用它來應用不同的文本格式。 這是代碼:
Vue.directive("format", function(el, binding, vnode) { const modifiers = binding.modifiers; if (modifiers.underline) { el.style.textDecoration = "underline"; } if (modifiers.bold) { el.style.fontWeight = "bold"; } if (modifiers.highlight) { el.style.background = "#ffff00"; } });
在上面的代碼中,我們獲取修飾符對象並將其分配給名為修飾符的變量。 然后我們檢查我們支持的每個可能的修飾符。 如果存在該修飾符,則我們應用相應的文本修飾。
我們已將下划線修改器應用於單詞指南。 我們將粗體修飾符應用於配置/自定義。 我已將高亮修飾符應用於單詞 check out。
為了表明您可以將多個修飾符應用於自定義指令,我已將所有三個修飾符應用於文本 Installed CLI Plugins。
這是它的樣子:
Demo #6 v-hook-demo 顯示生命周期鈎子
之前我在您的自定義指令中討論了可用的生命周期鈎子。 如果希望自定義指令基於生命周期鈎子工作,則需要為代碼使用不同的格式。 您將擁有一個對象,而不是在自定義指令的名稱后面使用函數。 該對象上的鍵將是一個或多個可用的生命周期鈎子。
在代碼中,我在 About 視圖中添加了一些代碼。 代碼有一個按鈕。 單擊按鈕時,數字會更新。 在 HelloWorld 組件中,我已將 v-hook-demo 組件應用於第一個 div。
這是 v-hook-demo 組件的代碼:
Vue.directive("hook-demo", { bind(el, binding, vnode) { console.log("bind"); }, inserted(el, binding, vndoe) { console.log("inserted"); }, updated(el, binding, vnode) { console.log("updated"); }, componentUpdated(el, binding, vnode, oldVnode) { console.log("componentUpdated"); } });
如果刷新屏幕並查看控制台,您會注意到已實現綁定和插入的生命周期掛鈎。 如果您轉到 “About” 頁面並單擊該按鈕,您將看到實現了 componentUpdated 生命周期鈎子。
結論
本文概述了在 Vue.js 中組成指令的項目。 在介紹之后,我將向您介紹創建自定義指令的六個示例。 這些示例顯示了一個基本的自定義指令,一個傳遞值的指令,一個使用參數的指令以及一個使用修飾符的指令。 最后一個示例顯示了可用的生命周期鈎子。
我希望你喜歡這篇文章。 如果您有任何疑問或想留下反饋,請發表評論。