在vue中建立自定義指令
原文: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 中組成指令的專案。 在介紹之後,我將向您介紹建立自定義指令的六個示例。 這些示例顯示了一個基本的自定義指令,一個傳遞值的指令,一個使用引數的指令以及一個使用修飾符的指令。 最後一個示例顯示了可用的生命週期鉤子。
我希望你喜歡這篇文章。 如果您有任何疑問或想留下反饋,請發表評