Vue自定义指令的用法
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 钩子中可用。
应用场景
防抖
图片懒加载
一键复制功能
…