指令是 Vue 中以 v- 开头的一种属性,像 v-showv-model 都属于 Vue 的内置指令。除了内置的指令外,Vue 也允许自定义指令。自定义指令的功能就是操作 DOM。虽然 Vue 可以通过改变数据来操作 DOM,但有的功能还是无法实现,只能直接操作底层 DOM。

全局指令

全局指令可以在单独的 JS 文件中定义,定义完成后只需要在 main.js 中引入,所有组件都能使用。

下面定义一个改变元素字体颜色的指令:

export default Vue => {
  //  定义指令
  Vue.directive('color', {
      //  元素被插入到父元素时调用
    inserted(el) {
      el.style.color = 'red'  //  设置字体为红色
    }
  })
}

main.js 中引入和注册指令:

import color from './directive'  //  引入指令
Vue.use(color)  //  注册指令

在组件中调用指令:

<button v-color>按钮</button>

button 的字体颜色会变为红色。

指令可以通过 Vue.directive 来定义。

Vue.directive 的第一个参数是指令名称,第二个参数是配置对象,对象中包含了一些钩子函数。

下面是钩子函数说明:

bind:只会调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。

inserted:被绑定元素插入父节点时调用,此时已经可以获取父元素了。

update:所在组件的虚拟 DOM 更新时调用。

componentUpdated:指令所在组件的虚拟 DOM 及其子虚拟 DOM 全部更新后调用。

unbind:只调用一次,指令与元素解绑时调用。

上面的几个钩子函数中 bindinserted 可能会用的多一些。

钩子函数又可以接收几个参数,下面是参数说明:

el:指令所绑定的元素,可以用来直接操作 DOM 。

binding:一个对象,包含下面几个属性:

  • name:指令名,不包含 v- 前缀。
  • value:指令的绑定值,如果指令是 v-color="1 + 1"value 的值就是 2
  • oldValue:指令绑定的前一个值,仅在 updatecomponentUpdated 钩子中可用。无论值是否改变都可用。
  • expression:字符串形式的指令表达式。如果 v-color="1 + 1"expression 的值就是 1 + 1
  • arg:传给指令的参数,可选。如果 v-color:bgarg 的值就是 bg
  • modifiers:一个包含修饰符的对象。如果 v-center.top.leftmodifiers 的值就是 {top: true, left: true}

vnode:Vue 编译生成的虚拟节点。

oldVnode:上一个虚拟节点,仅在 update componentUpdated 钩子中可用。

局部指令

局部指令需要在组件中的 directives 内定义。局部指令只能在定义的组件中使用。

下面用自定义局部指令实现页面打开后让 input 获取焦点:

<template>
  <div id="app">
    <input type="text" v-focus>
  </div>
</template>
export default {
  name: "app",
  directives: {
    //  定义名为 focus 的组件  
    focus: {
      //  元素插入到父节点
      inserted(el) {
        el.focus()  //  获取焦点
      }
    }
  }
}

页面打开后 input 就能直接获取焦点。

局部指令的钩子函数和参数和全局指令是一样的。

对象字变量

如果指令需要多个值,可以传入一个 JavaScript 对象字面量。指令函数能够接受所有合法的 JavaScript 表达式。

指令:

Vue.directive('margin', {
  inserted(el, binding) {
    el.style.marginTop = binding.value.top + 'px'
    el.style.marginLeft = binding.value.left + 'px'
  }
})

调用:

<input type="text" v-margin="{top: 100, left: 100}">

最终 inputmargin-topmargin-left= 100px

相关文章: