文章目录
- 自定义指令
- 局部指令
- 回调函数形式
- 配置对象形式
- 全局配置
- 回调函数形式
- 配置对象形式
Vue学习目录
上一篇:(十六)Vue之内置指令
先看两个需求:
- 需求1:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍。
- 需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点。
自定义指令
定义语法:
- (1).局部指令:在new Vue实例中配置
directives:{指令名:配置对象} 或 directives{指令名:回调函数} - (2).全局指令:在new Vue实例外配置
Vue.directive(指令名,配置对象) 或 Vue.directive(指令名,回调函数)
回调函数
函数何时会被调用?
- 1.指令与元素成功绑定时(一上来)。
- 2.指令所在的模板被重新解析时。
回调函数的参数有:
- el: 指令所绑定的元素,可以用来直接操作 DOM 。
- binding: 一个对象,包含以下属性:
- name: 指令名,不包括 v- 前缀。
- value: 指令的绑定值, 例如:
v-my-directive="1 + 1"
, value 的值是 2。 - oldValue: 指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。这两个钩子是生命周期钩子,以后再说
- expression: 绑定值的表达式或变量名。 例如
v-my-directive="1 + 1"
,
expression 的值是 “1 + 1”。 - arg: 传给指令的参数。例如 v-my-directive:foo, arg 的值是 “foo”。
- modifiers: 一个包含修饰符的对象。 例如:
v-my-directive.foo.bar
, 修饰符对象 modifiers的值是{ foo: true, bar: true }
。
- vnode: Vue 编译生成的虚拟节点。
- oldVnode: 上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
配置对象中的回调:
- (1)bind:指令与元素成功绑定时调用。(常用)
- (2)inserted:指令所在元素被插入页面时调用。(常用)
- (3)update:指令所在模板结构被重新解析时调用。(常用)
- (4)componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。
- (5)unbind: 只调用一次, 指令与元素解绑时调用。
(钩子:这个以后再说,现在先理解为函数)常用的是前三个
注意点:
- 1.指令定义时不加v-,但使用时要加v-;
- 2.指令名如果是多个单词,要使用kebab-case命名方式。
- 3.this是window
局部指令
局部指令在new Vue实例中使用directives配置项配置
回调函数形式
<div id="root">
<h2>{{name}}</h2>
<h2>当前的n值是:<span v-text="n"></span> </h2>
<h2>放大10倍后的n值是:<span v-big="n"></span> </h2>
<button @click="n++">点我n+1</button>
<hr/>
<input type="text" v-fbind:value="n">
<hr/><hr/>
</div>
data:{
name:'自定义指令',
n:1
},
directives:{
big(element,binding) {
element.innerText = binding.value * 10
},
fbind(element,binding){
element.value = binding.value
element.focus()
},
}
效果:实现了需求1,但是需求2的默认获取焦点没有实现,这是因为回调函数其中一个调用时机是一上来就会被调用,也就是元素还没插入页面就会被调用,元素还没有插入页面就获取焦点,显然是不可行的,这是一个顺序问题,所以回调函数实现不了需求2,需要用配置对象实现。
配置对象形式
directives:{
big(element,binding) {
element.innerText = binding.value * 10
},
/*fbind(element,binding){
element.value = binding.value
element.focus()
},*/
fbind:{
//指令与元素成功绑定时(一上来)
bind(element,binding){
element.value = binding.value
},
//指令所在元素被插入页面时
inserted(element,binding){
element.focus()
},
//指令所在的模板被重新解析时
update(element,binding){
element.value = binding.value
}
}
}
效果:所有需求都能实现
全局配置
如果多个容器使用同一个自定义指令,可以配置成全局配置。
在new Vue实例外使用Vue.directive配置
回调函数形式
<div id="root2">
<h2>当前的n值是:<span v-text="n"></span> </h2>
<input type="text" v-fbind:value="n">
</div>
Vue.directive('fbind',(element,binding)=>{
element.value = binding.value
element.focus()
})
new Vue({
el: '#root2',
data: {
n: 10
},
})
效果:同样实现不了需求2
配置对象形式
Vue.directive('fbind',{
//指令与元素成功绑定时(一上来)
bind(element,binding){
element.value = binding.value
},
//指令所在元素被插入页面时
inserted(element,binding){
element.focus()
},
//指令所在的模板被重新解析时
update(element,binding){
element.value = binding.value
}
})
效果:发现只有下面的文本框获取焦点,这是因为只能获取一个焦点,不能获取多个焦点,并且模板解析是从上往下解析,解析到第一个文本框就获取焦点,然后就是下一个文本框获取焦点,直到没有文本框为止。