我们都知道在Vue中存在了很多个指令,如v-bind、v-for等,实现了一些特定的功能,此时头疼的事情来了,如果这些指令里没有我们需要的功能,那么我们只能通过自己来编写原生JS获取目标节点来实现,但是在Vue中不提倡我们这样做,那我们该怎么办呢?
Vue给我们提供了一个很有意思的功能,自己编写指令来实现自己需要的功能。
1、全局指令
同全局过滤器一样,我们使用全局Vue来定义全局指令。下面以自定义v-focus指令来举例如何创建自定义指令。
Vue.directive(‘focus’,{....})-------第一个参数focus是指令名称,使用时要加v-。第二个参数是一个对象,这个对象有五个钩子函数
- bind:在指令第一次绑定到元素上时立即调用,只发生一次,用处是可以进行一次性的初始化设置。与样式有关的在这编写
- inserteds:在指令绑定元素插入DOM树上时发生。只发生一次,用处比较多。与JS行为有关的在这里编写
- update:在绑定元素更新时就发生。可发生多次。
-
componentUpdated
:指令所在组件的 VNode 及其子 VNode 全部更新后调用。 -
unbind
:只调用一次,指令与元素解绑时调用。
这些钩子函数的第一个参数el是绑定了该自定义指令的元素节点。
第二个参数为binding,它是一个对象其中包括了很多的属性。
比较重要的是:
-
name-------------指令的名称
-
value-------------指令的绑定值(计算表达式),例如:v-mydirective="1+1"则binding.value=2
-
expression-----字符串形式的指令表达式(输出字符串),例如v-mydirective="1+1"则binding.expression="1+1"。
有关更多的自定义指令参数信息可以前往Vue官方文档查看https://cn.vuejs.org/v2/guide/custom-directive.html?#%E9%92%A9%E5%AD%90%E5%87%BD%E6%95%B0
<div id="app" >
<input style="width: 200px" type="text" :value="msg" v-focus>
<!--v-focus正确使用-->
</div>
<script>
Vue.directive('focus',{ //这里的指令名称是focus,那么我们在使用时就要在前面添加v-
inserted:function (el) {
el.focus();
}
});
var vm=new Vue({
el:"#app",
data:{
msg:"聚焦"
},
methods:{
}
})
</script>
运行结果:
我们使用自定义全局指令Vue.directive('focus',{inserted:....})来创建一个v-focus指令,钩子函数我们为什么要使用inserted呢?bind钩子函数的作用是,在指令绑定到元素时就调用了,这时候还没有生成DOM树,是无法得到焦点的,综上所述我们只能使用inserted。
再看下面的这个例子:
<div id="app" >
<input style="width: 200px" type="text" :value="msg" v-color="'blue'" >
</div>
<script>
Vue.directive("color",{
bind:function (el,binding) {
el.style.color=binding.value;
console.log(binding.value);
console.log(binding.expression);
}
});
var Vm=new Vue(
{
el:"#app",
data:{
msg:"嗨,你好啊"
},
filters:{
},
methods:{
}
}
)
</script>
运行结果:
在这里我们使用了钩子函数的第二个参数"binding",它是一个对象,具有多个属性,这个例子与上一个不同之处在于,上一处我们没有往钩子函数中传入参数,而这一回,我们传入了参数(这里可以看到我们传入的blue是使用 ' ' 包含住的,如果不使用这个的话,那vue就会往data中寻找blue变量的了)使用binding.value获取到传入的参数,如果是binding.expression的话那么干获取到的就是一个字符串'blue'了。
2、局部自定义指令
既然有全局自定义指令,那么就应该有局部自定义指令,自定义指令的定义同自定义的过滤器一样,都是在Vue实例中定义的,与全局定义指令不同的是directive要加s变成directives。
<div id="app" >
<input style="width: 200px" type="text" :value="msg" v-color="'blue'" >
</div>
<script>
var Vm=new Vue(
{
el:"#app",
data:{
msg:"嗨,你好啊"
},
filters:{
},
methods:{
},
directives:{
'color':{bind:function (el,binding) { //指令名color
el.style.color=binding.value;
}}
}
}
)
</script>
运行结果:
我们可以看到,在Vue实例中定义自定义指令,是要在directives中使用键值对的形式去定义
3、简写形式
有时候我们希望在bind和update上做重复的动作,那么我们可以使用自定义指令的简写形式。
-
全局定义指令:Vue.deirective("color",function(el,binding){....})
-
自定义指令:directives{"color":function(el,binding){....}}
要注意在简写模式下的function指的永远是bind或update钩子函数