一.引例:两个需求
定义一个v-big指令,与v-text功能类似,但是会把绑定的数字放大10倍
定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获得焦点
需求1实现:
首先准备好一个容器,显示当前的数值以及放大10倍之后的数值,点击按钮绑定的数值加一。
<div id="root">
<h2>当前的n值是:<span v-text="n"></span> </h2>
<h2>放大10倍后的n值是:<span v-big="n"></span> </h2>
<button @click="n++">点我n+1</button>
<hr/>
</div>
创建Vue实例对象,n为所绑定的数值,初始值为1,在directives里添加v-big指令。将big指令写成函数式,函数式指令的弊端是无法处理细节上的问题,由于要与需求2做对比,需求1采用函数式。
new Vue({
el:'#root',
data:{
n:1
},
directives:{
big(element,binding){
element.innerText = binding.value * 10
}
}
})
自定义指令函数可以接收到两个参数:
(1)element:所绑定的真实DOM元素
(2)binding:是一个对象,包含指令名,所绑定的值(value)等
需求2实现:
首先定义输入框
(1)错误实现思路:
采用函数式定义指令,试图通过在函数体内添加focus()方法实现默认获得焦点功能
![](https://i-blog.csdnimg.cn/blog_migrate/35f1fe8466bc94495b4ccc5a92148d64.png)
用这种方法会导致:
页面一打开焦点并不会默认获得
点击+1按钮之后,输入框才会获得焦点
原因:focus()执行时机有问题
指令函数只有在指令与元素成功绑定(而不是成功放入页面)时才会被第一次调用,成功绑定只是两者在内存中建立了联系,而页面的呈现是母版解析完成的结果,调用函数成功绑定时页面还没有解析完成,还没有input。
点击按钮之后母版所依赖的数据n发生改变,会重新进行解析,在此之前页面已经有元素呈现,Vue不仅解析完成而且还调用了函数,所以点击按钮事件自然会使输入框获得焦点。
(2)正确实现方法:
指令采用对象式,里面所包含的方法会在合适的时机被分别调用。
fbind:{
//指令与元素成功绑定时(一上来)
bind(element,binding){
element.value = binding.value
},
//指令所在元素被插入页面时
inserted(element,binding){
element.focus()
},
//指令所在的模板被重新解析时
update(element,binding){
element.value = binding.value
}
}
二.定义语法
(1).局部指令:
new Vue({ directives:{指令名:配置对象} })
new Vue({ directives{指令名:回调函数} })
(2)全局指令:
Vue.directive(指令名,配置对象)
Vue.directive(指令名,回调函数)
(3)备注
1.指令定义时不加v-,但使用时要加v-;
2.指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名。