基本

除了核心中提供的默认指令集之外,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"
})