Vue除了核心功能默认内置的指令 ,Vue 也允许注册自定义指令。
自定义指令是用来操作DOM的。尽管Vue推崇数据驱动视图的理念,但并非所有情况都适合数据驱动。自定义指令就是一种有效的补充和扩展,不仅可用于定义任何的DOM操作,并且是可复用的。
写一个自定义指令的两种方式:
- 全局指令: 通过 Vue.directive() 函数注册一个全局的指令。
- 局部指令:通过组件的 directives 属性,对该组件添加一个局部的指令。
创建全局指令:
需要传入指令名称以及一个包含指令钩子函数的对象,该对象的键即钩子函数的函数名,值即函数体,钩子函数可以有多个。
Vue.directive("focus", {
inserted: function(el){
el.focus();
}
})
创建局部指令:
通过在Vue实例中添加 directives 对象数据注册局部自定义指令。
directives: {
focus: {
inserted: function(el){
el.focus();
}
}
}
下面我们就具体讲一下怎么在实战中运用自定义指令:
需求:有些网站图片的加载做得非常优雅,在图片未完成加载前,用随机的背景色占位,图片加载完成后才直接渲染出来。用自定义指令可以非常方便的实现这个功能。
<div id="app" v-image = "item " v-for="item in imageList"></div>
<script>
Vue.directive("image", {
inserted: function(el,binding){
var color = Math.floor(Math,random()*1000000)
el.style.backgroundColor = "#" + color
var img = new Image()
img.src = binding.vaule
img.onload = function(){
el.style.backgroundImage = “url(” + binding.vaule + ")"
}
}
})
new Vue({
el: "#app",
data: {
imageList: [
{
url: "http://consumer-img.huawei.com/content/dam/huawei-cbg-site/greate-china/cn/mkt/homepage/section4/home-s4-p10-plus.jpg"
},
{
url: "http://consumer-img.huawei.com/content/dam/huawei-cbg-site/greate-china/cn/mkt/homepage/section4/home-s4-watch2-pro-banner.jpg"
},
{
url: "http://consumer-img.huawei.com/content/dam/huawei-cbg-site/en/mkt/homepage/section4/home-s4-matebook-x.jpg"
}
]
}
})
</script>
自定义指令的钩子函数
一个指令定义对象可以提供如下几个钩子函数 (均为可选):
- bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
- inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
- update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 。
- componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
- unbind:只调用一次,指令与元素解绑时调用。
钩子函数参数(即 el、binding、vnode 和 oldVnode)
- el:指令所绑定的元素,可以用来直接操作 DOM。
- binding:一个对象,包含以下 property:
- name:指令名,不包括 v- 前缀。
- value:指令的绑定值。
- oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
- expression:字符串形式的指令表达式。
- arg:传给指令的参数。
- modifiers:一个包含修饰符的对象。
- vnode:Vue 编译生成的虚拟节点。
- oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
应用场景
- 防抖
- 图片懒加载
- 一键复制功能
- …
具体详细用法vue.js官网有详细介绍,可以点击查看并学习!