指令是什么
在vue
中以v-
开头的行内属性,都是指令。如我们常见的v-model、v-on、v-show
都是指令。指令的职责是,当指令中的表达式的值改变时,将响应式地作用于 DOM
。
<p v-if="seen">现在你看到我了</p>
这里,v-if
指令将根据表达式seen
的值的真假来插入/移除 <p>
元素。
既然指令的职责可以实现响应式,那vue
默认提供的几个肯定是不够用的,所以vue
也提供了注册自定义指令功能。
什么使用自定义指令
上文也说到指令可以实现数据响应式
功能。
那么我们如何实现呢?
如何自定义指令
可分为全局定义和局部定义
全局定义
在directive/focus下创建
import Vue from 'vue'
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function(el) {
// 聚焦元素
el.focus()
}
})
在main.js
导入
import '@/directive/focus/index'
在组件中使用
<input v-focus />
局部定义
组件中也接受一个 directives 的选项:
<template>
<div>
<input v-focus />
</div>
</template>
<script>
export default {
name: "CustomInstructDemo",
directives: {
focus: {
// 指令的定义
inserted: function (el) {
el.focus();
},
},
},
data() {
return {};
},
methods: {},
};
</script>
然后你可以在模板中的元素上使用新的 v-focus
属性,如下:
<input v-focus>
钩子函数
自定义指令中的函数,一个指令定义对象可以提供如下几个钩子函数 (均为可选):
bind
:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。inserted
:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。update
:所在组件的VNode
更新时调用,但是可能发生在其子VNode
更新之前。componentUpdated
:指令所在组件的VNode
及其子VNode
全部更新后调用。unbind
:只调用一次,指令与元素解绑时调用。
钩子函数参数
指令钩子函数会被传入以下参数:
el
:指令所绑定的元素,可以用来直接操作DOM
。binding
:一个对象,包含以下property
:name
:指令名,不包括v-
前缀。value
:指令的绑定值。(常用)oldValue
:指令绑定的前一个值,仅在update
和componentUpdated
钩子中可用。无论值是否改变都可用。expression
:字符串形式的指令表达式。arg
:传给指令的参数,可选。modifiers
:一个包含修饰符的对象。vnode
:Vue 编译生成的虚拟节点。oldVnode
:上一个虚拟节点,仅在update
和componentUpdated
钩子中可用。
指令动态参数
通过上面的钩子函数参数,我们知道binding
就是外部输入的参数对象,我们可以从binding
中渠道参数,然后再去做匹配,实现动态参数的效果。
import Vue from 'vue'
Vue.directive('pin', {
bind: function(el, binding, vnode) {
el.style.position = 'fixed'
const s = (binding.arg === 'right' ? 'right' : 'top')
el.style[s] = binding.value + 'px'
el.style.color = '#333'
}
})
在main.js
中引入
import '@/directive/pin/index'
在组件中使用
<div id="dynamicexample">
<h3 style="color: #333333">Scroll down inside this section ↓</h3>
<p v-pin:[direction]="200">I am pinned onto the page at 200px to the left.</p>
</div>
data() {
return {
direction: 'right',
}
},
效果示例