什么是指令:
指令只一种可以附加到DOM元素的微命令(tiny commands). 它们通常以"v-"作为前缀, 以方便Vue知道你在使用一种特殊的标记, 从而确保语法的一致性. 如果你需要对HTML元素的低级别(low-level)访问来控制一些行为, 它们通常很有用.
创建自定义指令:
Vue.directive( 'directiveName' )
在html中使用:
<div v-directiveName class="ele"></div>
五个钩子函数:
(1) bind:指令附加到元素时触发,且只触发一次
(2) inserted:元素非添加到父元素时触发
(3) update:每当元素本身更新(但子元素还未更新)时触发
(4) componentUpdate:每当组件和子组件被更新时触发
(5) unbind:一旦指令被移除时触发
下边图片很形象解释了这5个钩子函数
钩子参数:
每个钩子都有el,binding,vnode参数,update和componentUpdate钩子还暴露了oldVnode用来区分传递的参数时新值还是旧值。
el: 绑定的元素,通过它可直接操作dom;
binding:首先它是一个对象,里边有以下参数:
name:指令名,不包含v-前缀
value:为指令的绑定值,如: <div v-directive="20"></div> ,20就是value;当然绑定的值也可以时表达式或对象
oldValue:指令绑定之前的值,只能在update和componentUpdate中有这个值
expression:字符串形式的指令表达式,意思就是只有绑定的值为一个表达式的时候,才会有expression这个参数
<template>
<div>
<h1>son</h1>
<input v-focus="1+1" type="text" placeholder="name">
</div>
</template>
<script>
import Vue from 'vue'
Vue.directive('focus', {
bind(el, binding, vnode) {
console.log('binding', binding)
}
})
arg:传给指令的参数,如:<div v-derective:foo="1"></div> ,foo就是arg
modifiers:一个包含指令修饰符的对象,如:
<template>
<div>
<h1>son</h1>
<input v-focus.enter="1+1" type="text" placeholder="name">
</div>
</template>
<script>
import Vue from 'vue'
Vue.directive('focus', {
bind(el, binding, vnode) {
console.log('binding', binding)
}
})vnode:vue在编译时生成的虚拟节点。
oldVnode:更新之前的虚拟节点,只有update和componentUpdate钩子函数有此参数。
小练习:
1、为指令绑定字符串参数、传递参数
<template>
<div>
<h1>son</h1>
<input v-position:top="20" type="text" placeholder="name">
</div>
</template>
<script>
import Vue from 'vue'
Vue.directive('position', {
bind(el, binding, vnode) {
el.style.position = "relative"
el.style[binding.arg] = binding.value + "px"
}
})
</script>
2、指令绑定的值为对象
<template>
<div>
<h1>son</h1>
<input v-position="{top: 20, left: 20}" type="text" placeholder="name">
</div>
</template>
<script>
import Vue from 'vue'
Vue.directive('position', {
bind(el, binding, vnode) {
el.style.position = "relative"
el.style.top = binding.value.top + "px"
el.style.left = binding.value.left + "px"
}
})
</script>
3、vue官网的一个例子:页面显示,输入框自动聚焦
<template>
<div>
<h1>son</h1>
<input v-focus type="text" placeholder="name">
</div>
</template>
<script>
import Vue from 'vue'
Vue.directive('focus', {
inserted(el, binding, vnode) {
el.focus()
}
})
</script>