Vue自定义指令

Vue自定义指令

某些情况仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。

比如:获取文本框的焦点(autofocus有兼容性问题,vue中默认无法使用,需要用到表单的focus方法,vue推荐将此方法封装成自定义指令)

自定义指令

  • 定义一个全局的指令
1
2
3
4
5
6
7
8
9
10
11
// 语法:Vue.directive(参数1, 参数2)
// 参数1:指令的名称
// 参数2:指令的配置项(钩子函数)
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时…
// el: 当前绑定的元素
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
  • 使用自定义指令
1
2
<!-- 使用时需要添加v-前缀,起名时不要和默认的14个指令冲突 -->
<input v-focus>

全局指令与局部指令

  • 定义全局指令
1
2
3
4
5
Vue.directive('focus', {
inserted(el) {
el.focus()
}
})
  • 定义局部指令
1
2
3
4
5
6
7
8
9
const vm = new Vue({
directives: {
focus: {
inserted(el) {
el.focus()
}
}
}
})

指令的钩子函数

  • bind: 只会调用一次,当指令绑定到当前元素上时调用
  • inserted: 被绑定元素插入父节点时调用
  • update: 指令的值发生改变的时候
  • componentUpdated: 指令所在的组件中所有的DOM都更新完成的时候
  • unbind:只调用一次,指令与元素解绑时调用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Vue.directive('focus', {
// 只会调用一次,当指令绑定到当前元素上时调用,可以理解为在内存中绑定。可以用来模拟指令的修饰符
bind (el) {

},
// 当前元素被插入到父节点的时候调用(渲染时),此时可以操作dom
inserted (el) {
el.focus()
},
// 当指令对应的数据发生改变的时候调用,可以用来模拟v-model
update () {

},
// 会等待当前组件以及子组件的vue内部节点都更新完成后调用
componentUpdated () {

},
// 指令与元素解绑的时候调用,例如vue实例执行$destroy方法时
unbind () {

}

})

钩子函数的参数

所有的钩子函数两个参数elbinding

  • 指令的组成
1
2
v-指令名:指令参数.指令修饰符.指令修饰符 = "指令的值"
v-on:click.enter.prevent = "clickFn"
  • 指令的参数
1
2
3
4
5
6
7
8
el: 当前元素
binding:一个对象,包含以下属性:
name:指令名,不包括 v- 前缀。
value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2
oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"
arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"
modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。

指令的简写

如果配置的钩子函数 bindupdate 的逻辑是一模一样的,可以这样简写:Vue.directive(指令名, 函数)

1
2
3
Vue.directive('bgcolor', function (el, binding) {
el.style.backgroundColor = binding.value
})