💂 个人网站: 【紫陌】【笔记分享网】
💅 想寻找共同学习交流、共同成长的伙伴, 请点击【前端学习交流群】
1.什么是自定义指令?
v-开头的行内属性,都是指令,不同的指令可以完成或实现不同的功能。除了内置指令外,Vue 也允许注册自定义指令。有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候使用自定义指令更为方便。而vue中的内置指令例如v-show只不过是vue帮你动了dom上的display属性,所以自定义指令,就是自己亲手对原生操作dom进行了一次封装
自定义指令文档: https://cn.vuejs.org/v2/guide/custom-directive.html
2.如何自定义指令
自定义指令有局部指令和全局指令
局部指令
局部指令有函数形式和对象形式
提一个需求:定义一个v-big指令,让它和v-text功能类似,把绑定的值放大10倍
函数形式:
<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>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
name:'我爱紫陌',
n:1
},
directives:{
//big函数何时会被调用?1.指令与元素成功绑定时(一上来)。2.指令所在的模板被重新解析时。
big(element,binding){
console.log('big',this) //注意此处的this是window
console.log(element,binding)
element.innerText = binding.value * 10
},
}
})
</script>
这时候我们打印了一下big()函数的参数(原生DOM,指令信息一般都是操作value)
效果图:
提第二个需求:定义一个v-sbind指令,和v-bind功能类似,可以让其绑定的input元素默认获取焦点
尝试用函数形式写:
效果:
刷新没有对焦。
这是为什么呢?
其实是focus执行时间点的问题,指令与元素成功绑定时就会调用指令函数,成功绑定只是在内存中建立了这种绑定关系,并没有放入页面,而一上来input框就已经调用了指令函数,因此对input进行焦点的获取是不起作用的。
所以对于这种情况,我们必须精确到元素放入页面的时间点,而指令的函数式写法是不符合该需求的,这样就用到了指令的对象式写法。
对象写法
对象里面有三个固定的钩子函数,表示哪个时间段触发。
这三个函数也有两个参数跟函数形式一样,第一个是原生DOM,第二个指令信息
zbind: {
// 指令与元素成功绑定时(一上来)
bind(element, bidding) {
// 虽然没放入页面但是不影响赋值
element.value = bidding.value
},
// 指令所在元素被插入页面时
inserted(element, bidding) {
// 此时我们就可以在元素插入页面时再调用获取焦点事件
element.focus()
},
// 指令所在的模板被重新解析时
update(element, bidding) {
// 页面重新解析时,同样需要再次赋值,这样可以保证num的值随之变化
element.value = bidding.value
}
}
从上面代码可以看出,bind事件和update其实是一样的,而指令的函数式就是包含的这两个方法,只不过没有inserted方法,因此遇到特殊情况就用对象式,其他情况函数式就可以满足需求
全局指令
<div id="root">
<h2>{{name}}</h2>
<h2>当前的n值是:<span v-text="n"></span> </h2>
<!-- <h2>放大10倍后的n值是:<span v-big-number="n"></span> </h2> -->
<h2>放大10倍后的n值是:<span v-big="n"></span> </h2>
<button @click="n++">点我n+1</button>
<!-- <hr/>-->
<input type="text" v-zbind:value="n">
</div>
<script type="text/javascript">
//定义全局指令
Vue.directive('zbind', {
//指令与元素成功绑定时(一上来)
bind(element, binding) {
element.value = binding.value
},
//指令所在元素被插入页面时
inserted(element, binding) {
element.focus()
},
//指令所在的模板被重新解析时
update(element, binding) {
element.value = binding.value
}
})
new Vue({
el: '#root',
data: {
name: '我爱紫陌',
n: 1
},
directives: {
big(element, binding) {
element.innerText = binding.value * 10
},
}
})
</script>
效果也是一样的:
全局指令在项目当中都是放在main.js文件当中,然后全部页面可以直接使用指令
使用场景
- 普通DOM元素进行底层操作的时候,可以使用自定义指令
- 自定义指令是用来操作DOM的。尽管Vue推崇数据驱动视图的理念,但并非所有情况都适合数据驱动。自定义指令就是一种有效的补充和扩展,不仅可用于定义任何的DOM操作,并且是可复用的。
点赞支持