内容提要:
- 自定义指令基本用法介绍
- 自定义指令内部包含哪些钩子函数
- 指令钩子内部传递哪些元素值
- 自定义指令函数的缩略写法用例
- 在JavaScript对象中传递多个字面值
介绍
除了在核心附带的默认的指令集合(v-model
和v-show
)外,Vue也允许你注册自定义指令。注意在Vue 2.0,代码重用和抽象的主要形式是组件-然而,可能某些情况下你可能需要针对原生元素进行一些底层的DOM访问,这就是定制元素仍然有用的地方,一个例子是聚焦一个输入框,像这样:
当页面加载的时候,元素获得焦点(注意:autofocus
在手机的Safari上无效)。实际上,如果你访问本页后没有点击任何其他的地方,上面的输入框应用获得焦点。现在让我们构建指令实现这个:
// 注册一个全局的自定义指令称为“v-focus”
Vue.directive('focus', {
// 当绑定到元素插入到DOM时
inserted:function (el) {
// 焦点元素
el.focus()
}
})
如果你想注册一个局部指令,组件页接受directives
操作项:
direcitives: {
focus: {
// 指令定义
inserted: function (el) {
el.focus()
}
}
}
在模板内,你能在任何元素使用v-focus
属性,像这样:
<input v-focus>
钩子函数
一个指令定义对象能够提供一些钩子函数(所有的都是可选):
-
bind
:仅被调用一次,当指令第一次绑定到元素时,在这里,你可以做一些一次性设置工作 -
inserted
:当组件元素被插入到父节点的时候调用(这只保证父节点的存在,不一定在文档中)。 -
update
:包含组件的VNode被更新之后调用,但可能在它的子组件更新之前更新。指令的值可能改变也可能不变,但你能跳过不需要的更新通过对比当前的绑定值和旧值(参见下面的钩子参数)。我们稍后later将更详细的介绍VNodes,当我们渲染函数的时候 render functions。
-
componentUpdated
:包含组件的VNode和它的子组件的VNodes被更新之后调用。 -
unbind
: 仅仅被调用一次,当指令从元素解绑是调用。
通过这些钩子我们可以查询如下属性(例如:el
,binding
,vnode
,和oldVnode
)在下一节。
指令钩子元素
指令钩子传递这些元素:
el
:指令绑定到的元素。这可以用来直接操作DOM。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”
。- 修饰符:包含修饰符的对象(如果有的话,例如在
v-my-directive.foo.bar
,修饰符对象是{ foo: true, bar: true }
.
vnode
: 通过Vue的编译器产生的虚拟node。详看 VNode API。oldVnode
:前一个虚拟node,仅在update
和componentUpdated
钩子可用。
除了
el
之外,你要以只读的方式对待这些参数,并且不要修改。如果你需要通过钩子分享信息,我们建议你通过元素的dataset操作.
使用这些属性的自定义指令的例子:
<div id="hook-arguments-example" v-demo: foo.a.b="message"></div>
Vue.directive('demo',{
bind: function (el, binding, vnode) {
var s = JSON.stringify
el.innerHTML =
'name:' + s(binding.name) + '<br>' +
'value:' + s(binding.value) + '<br>' +
'expression:' + s(binding.expression) + '<br>'
'argument:' + s(binding.arg) + '<br>' +
'modifiers:' + s(binding.modifiers) + '<br>' +
'vnode keys:' + Object.keys(vnode).join(', ')
}
})
new Vue({
el: '#hook-arguments-example',
data: {
message: 'hello!'
}
})
函数简写
许多情况下,你可能想让bind
和update
有相同的行为,但不关心其它的行为,例如:
Vue.directive('color-swatch', function (el, binding) {
el.style.backgroundColor = binding.value
})
对象字面值
如果你的指令需要多个值,你也能够在一个JavaScript对象的字面值中传递。记住,指令能携带任何有效的JavaScript表达式。
<div v-demo="{ color: 'white', text: 'hello!'}"></div>
Vue.directive('demo', function (el, binding) {
console.log(binding.value.color) // => "white"
console.log(binding.value.text) // => 'hello!'
})