基本

除了核心中提供的預設指令集之外,Vue.js 還允許你註冊自定義指令。自定義指令提供了一種將資料更改對映到任意 DOM 行為的機制。

你可以使用 Vue.directive(id, definition) 方法註冊全域性自定義指令,傳入指令 ID,後跟定義物件。你還可以通過將其包含在元件的 directives 選項中來註冊本地自定義指令。

鉤功能

  • bind :當指令首次繫結到元素時,只呼叫一次。
  • 更新 :在 bind 之後第一次使用初始值呼叫,然後在繫結值更改時再次呼叫。提供新值和先前值作為引數。
  • unbind :當指令從元素中解除繫結時,只呼叫一次。
Vue.directive('my-directive', {
     bind: function () {
       // do preparation work
       // e.g. add event listeners or expensive stuff
       // that needs to be run only once
     },
     update: function (newValue, oldValue) {
       // do something based on the updated value
       // this will also be called for the initial value
     },
     unbind: function () {
       // do clean up work
       // e.g. remove event listeners added in bind()
     }    
})

註冊後,你可以在 Vue.js 模板中使用它(請記住新增 v- 字首):

<div v-my-directive="someValue"></div>

當你只需要 update 函式時,你可以傳入單個函式而不是定義物件:

Vue.directive('my-directive', function (value) {
  // this function will be used as update()
})

指令例項屬性

所有鉤子函式都將被複制到實際的指令物件中,你可以在這些函式中訪問它們作為 this 上下文。指令物件公開了一些有用的屬性:

  • el :指令繫結的元素。
  • vm :擁有此指令的上下文 ViewModel。
  • expression :繫結的表示式,不包括引數和過濾器。
  • arg :論證,如果存在的話。
  • name :指令的名稱,不帶字首。
  • 修飾符 :包含修飾符的物件(如果有)。
  • descriptor :包含整個指令的解析結果的物件。
  • params :包含 param 屬性的物件。解釋如下。

你應該將所有這些屬性視為只讀,並且永遠不要修改它們。你也可以將自定義屬性附加到指令物件,但要注意不要意外覆蓋現有的內部屬性。

使用其中一些屬性的自定義指令示例:

HTML

<div id="demo" v-demo:hello.a.b="msg"></div>

JavaScript 的

Vue.directive('demo', {
  bind: function () {
    console.log('demo bound!')
  },
  update: function (value) {
    this.el.innerHTML =
      'name - '       + this.name + '<br>' +
      'expression - ' + this.expression + '<br>' +
      'argument - '   + this.arg + '<br>' +
      'modifiers - '  + JSON.stringify(this.modifiers) + '<br>' +
      'value - '      + value
  }
})
var demo = new Vue({
  el: '#demo',
  data: {
    msg: 'hello!'
  }
})

結果

name - demo
expression - msg
argument - hello
modifiers - {"b":true,"a":true}
value - hello!

物件文字

如果你的指令需要多個值,你還可以傳入 JavaScript 物件文字。請記住,指令可以採用任何有效的 JavaScript 表示式:

HTML

<div v-demo="{ color: 'white', text: 'hello!' }"></div>

JavaScript 的

Vue.directive('demo', function (value) {
  console.log(value.color) // "white"
  console.log(value.text) // "hello!"
})

文字修飾語

當指令與文字修飾符一起使用時,其屬性值將被解釋為普通字串並直接傳遞給 update 方法。update 方法也只會呼叫一次,因為普通字串不能被動。

HTML

<div v-demo.literal="foo bar baz">

JavaScript 的

Vue.directive('demo', function (value) {
  console.log(value) // "foo bar baz"
})