Vue | 21 可複用性&組合-自定義指令

內容提要:

  1. 自定義指令基本用法介紹
  2. 自定義指令內部包含哪些鉤子函數
  3. 指令鉤子內部傳遞哪些元素值
  4. 自定義指令函數的縮略寫法用例
  5. 在JavaScript對象中傳遞多個字面值

介紹

除了在覈心附帶的默認的指令集合(v-modelv-show)外,Vue也允許你註冊自定義指令。注意在Vue 2.0,代碼重用和抽象的主要形式是組件-然而,可能某些情況下你可能需要針對原生元素進行一些底層的DOM訪問,這就是定製元素仍然有用的地方,一個例子是聚焦一個輸入框,像這樣:

input

當頁面加載的時候,元素獲得焦點(注意:autofocus在手機的Safari上無效)。實際上,如果你訪問本頁後沒有點擊任何其他的地方,上面的輸入框應用獲得焦點。現在讓我們構建指令實現這個:

// 註冊一個全局的自定義指令稱爲“v-focus”
Vue.directive('focus', {
    // 當綁定到元素插入到DOM時
    inserted:function (el) {
        // 焦點元素
        el.focus()
    }
})

如果你想註冊一個局部指令,組件頁接受directives 操作項:

direcitives: {
    focus: {
        // 指令定義
        inserted: function (el) {
            el.focus()
        }
    }
}

在模板內,你能在任何元素使用v-focus屬性,像這樣:

<input v-focus>

鉤子函數

一個指令定義對象能夠提供一些鉤子函數(所有的都是可選):

  • bind:僅被調用一次,當指令第一次綁定到元素時,在這裏,你可以做一些一次性設置工作

  • inserted:當組件元素被插入到父節點的時候調用(這隻保證父節點的存在,不一定在文檔中)。

  • update:包含組件的VNode被更新之後調用,但可能在它的子組件更新之前更新。指令的值可能改變也可能不變,但你能跳過不需要的更新通過對比當前的綁定值和舊值(參見下面的鉤子參數)。

    我們稍後later將更詳細的介紹VNodes,當我們渲染函數的時候 render functions

  • componentUpdated:包含組件的VNode和它的子組件的VNodes被更新之後調用。

  • unbind: 僅僅被調用一次,當指令從元素解綁是調用。

通過這些鉤子我們可以查詢如下屬性(例如:elbindingvnode,和oldVnode)在下一節。

指令鉤子元素

指令鉤子傳遞這些元素:

  • el:指令綁定到的元素。這可以用來直接操作DOM。
  • binding:包含以下屬性的對象。
    • name:指令的名字,不帶v-前綴
    • value:被傳遞給指令的值。例如在v-my-directive=“1 + 1”,值是2
    • oldValue:舊值,僅在updatecomponentUpdated可用。無論值改變與否它都可用。
    • expression:作爲一個字符串綁定給表達式。例如在v-my-directive=“1 + 1”,表達式是“1 + 1”.
    • arg:傳遞給指令的參數(如果有的話),例如v-my-directive:foo,參數是“foo”
    • 修飾符:包含修飾符的對象(如果有的話,例如在v-my-directive.foo.bar,修飾符對象是{ foo: true, bar: true }.
  • vnode: 通過Vue的編譯器產生的虛擬node。詳看 VNode API
  • oldVnode:前一個虛擬node,僅在updatecomponentUpdated鉤子可用。

除了el之外,你要以只讀的方式對待這些參數,並且不要修改。如果你需要通過鉤子分享信息,我們建議你通過元素的dataset操作.

使用這些屬性的自定義指令的例子:

<div id="hook-arguments-example" v-demo: foo.a.b="message"></div>
Vue.directive('demo',{
    bind: function (el, binding, vnode) {
        var s = JSON.stringify
        el.innerHTML = 
            'name:' + s(binding.name) + '<br>' +
            'value:' + s(binding.value) + '<br>' + 
            'expression:' + s(binding.expression) + '<br>'
            'argument:' + s(binding.arg) + '<br>' + 
            'modifiers:' + s(binding.modifiers) + '<br>' + 
            'vnode keys:' + Object.keys(vnode).join(', ')
    }
})

new Vue({
    el: '#hook-arguments-example',
    data: {
        message: 'hello!'
    }
})

directive

函數簡寫

許多情況下,你可能想讓bindupdate有相同的行爲,但不關心其它的行爲,例如:

Vue.directive('color-swatch', function (el, binding) {
    el.style.backgroundColor = binding.value
})

對象字面值

如果你的指令需要多個值,你也能夠在一個JavaScript對象的字面值中傳遞。記住,指令能攜帶任何有效的JavaScript表達式。

<div v-demo="{ color: 'white', text: 'hello!'}"></div>
Vue.directive('demo', function (el, binding) {
    console.log(binding.value.color) // => "white"
    console.log(binding.value.text)   // => 'hello!'
})
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章