Custom Directives
這個部分要講自製 directive 的內容。
在自製 directive有以下幾個 hook 可以使用,分別為 bind, inserted, update, componentUpdated, unbind
以上這個範例可以看到我們自製了一個 directive 叫做 focus,然後,會在目標元素被掛到 DOM 上的時候,加入這個自製 directive 的效果。
另外,要特別注意的是自製 directive 要加在我們自製元件的 template 中喔,不要加到 HTML 文本裡面,會沒有效果。
那加入的內容有前綴詞是 v- ,它的後面就是加上我們自訂義的 directive 名稱,所以這邊的自製 directive 會是 v-directive。
全局註冊 v.s 局部註冊
全局註冊的方式,就是直接呼叫 Vue.directive 在物件外層註冊。
ex:
1 | Vue.directive('focus', { |
局部註冊:在元件內部註冊自訂義的 directive 的話,可以將其定義內容加到指定元件的 directives 屬性中。
ex:
1 | directives: { |
Hook Function
這邊稍微介紹一下,自訂的 directive 所擁有的 hook 有哪些
- bind: 只會被呼叫一次。它的被呼叫時機為,當自製的 directive 被綁定到指定元件上時,會被呼叫。這個 hook 可以用來初始化一個被綁定元件。
- inserted: 當被綁定元件插入父元件中時,此 hook 會被呼叫。
- update: 所在元件更新時會發動,有可能比其所在元件所擁有的子元件更新前發動。
- componentUpdated: 所在元件更新,且該元件所擁有的全部子元件也更新後發動。
- unbind: 當此 directive 解綁時會發動。
以上這個範例,我們可以看到當元件被插入 DOM 時,會觸發 bind 和 inserted 這兩個 Hook,當更改 input 中的內容時,會更新所在元件的 message 資料,此時,會觸發 update 和 componentUpdated 這兩個 hook。
function shorhand
在上面的範例,可以看到我們的 directive 再創的時候,是用物件形式寫法來做定義的內容。
而官方文件也有提供一個 function 的寫法,若用 function 的寫法來定義的話,該 directive 會預設含有 bind 和 update 這兩個 hook。
ex:
1 | Vue.directive('focus', function () { |
Directive Hook Arguments
在我們自訂義的 directive 所擁有的 hook 會帶入以下的參數
參數 | 內容 | 功能 |
---|---|---|
el | 可以取得 directive 所在的元件,可用來操縱所在元件的 DOM | |
binding | 它是一個物件,它包含了以下的屬性 | |
name | 可以取得此沒有加上 v- 這個前綴詞的 directive 名稱 | |
value | 傳給 directive 的值,可以被這個屬性取得 | |
oldValue | 可以取得 value 的上一個舊值,只能在 update 和 componentUpdated 這兩個 hook 被取得。不管 value 有沒有被更改內容,此屬性的值都能被取得 | |
expression | 取得傳給 directive 的字串,注意是字串型別喔!! | |
arg | 取得傳給 directive 的參數 | |
modifiers | 是一個具有修飾符的物件 | |
vnode | 由 Vue 編譯器所創出來的虛擬節點 | |
oldVnode | 前一個虛擬節點,只能在 update 和 componentUpdated 這兩個 hook 被取得 |
modifier feature
其中,modifiers 的引用方式比較特別一點,所以,在這邊紀錄一下
1 | Vue.directive('focus', function(el, binding) { |
上面這個內容你可以看到我們在定義 myComponent 元件的 template 部分綁上自訂義的 v-focus,然後,後面接著 landy.test1.test2,那我們可以在
它的 console 中的 binding 屬性中的 arg 屬性看到其內容為 landy ,而 modifiers 屬性裡面會是一個物件,裡面包裹著兩個屬性分別為 test1 和 test2,然後,它們的值皆為 true。
可以看出來,先用冒號指定 arg 的對象,接著,才在這個 arg 後面使用 modifiers。
Dynamic Directive Arguments
在官方文件有講到,我們可以動態的變換傳入 directive 的 arg。
1 | ---HTML=== |
可以看到我們用中括號把要傳入的 arg 內容包起來,那其 arg 的內容,可以由外部動態的更動,而 directive 可以利用 binding 的 arg 屬性來調用到這個傳入的 arg 內容。
Object Literals
direction 也可以接由外部傳進來的物件,接近來之後,我們再透過 direction 的 binding 的 value 內容來調用傳入的物件內容。
Alex 宅幹嘛 - 眉眉角角
Alex 提供的directive 範例
Alex 在課堂上提到一個它利用 directive 的功能來做的一個有關 grid system 展示的範例,因為,這個範例我蠻喜歡的,所以,紀錄一下
以上這個範例,我們先去偵聽 Vue 物件的 resize 事件,接著,在每一次觸發 resize 事件的時候,都會去更動到 Vue 物件中的 width 屬性值。
此時,我們利用我們自訂義的 v-width 這個 directive 來將 Vue 物件的 width 屬性值接進來,每當觸發 resize 就會去更動 v-width 所在元件的 directive 的 value 和 oldValue 值,
這個時候就會連帶的跑到 v-width 的 directive 定義的 function 裡面,去即時取得當下元件的寬度,顯示到畫面上,代表現在的格線區塊的寬度為多少,可以很好的展示給客戶看。
Directive 心法
注意~~~~~~~~~~~
以上這個範例, Alex 大大有傳遞一個觀念,我們可以偵聽較少元件的事件,並搭配 directive 的功用當其 binding 的數值因為偵聽事件觸發而變動,連帶的就會去觸發各 directive 所在的元件的 directive 定義的內容,以此機制去更動所在元件的內容。
用上面這種手法,我們就不需要每一個元件都要綁定屬於它自己的偵聽事件,當觸發多個偵聽事件時,可能因為多線程的緣故,而造成瀏覽器不可預知的錯誤,所以,可以想一下要怎麼利用 directive 這個工具喔~~