vue自定义指令

本文介绍了Vue中的指令系统,重点讲解自定义指令。阐述了自定义指令的定义格式、各钩子函数及其执行顺序和传入参数。还给出跳动增长数值的示例代码,以及在当前元素之外点击、元素全屏展示、元素拖动等其他示例代码地址,帮助理解其实际应用。

vue中的指令是指以v-开头并加在元素上的自定义属性,通过指令系统来增强其当作模板引擎的功能。常用的指令有:v-for, v-html, v-if, v-show等等。

在一些特殊场景下,我们也还是会需要去订制一些功能,此时我们就需要去自定义一些指令。

此外,自定义指令也是面试中经常会被问到的问题之一,你是否有使用过自定义指令也能从一定层面体现你是否经历过了复杂的业务要求。
简介

本文介绍了vue中的指令系统,介绍了自定义指令的使用格式,并举了一个本人在项目开中使用到的真实的自定义指令(附代码)。

阅读本文需要你有一定的vue基础。

内容

理解指令
定义及使用自定义指令
示例:跳动增长的数值
其它有用的示例及代码
小结
理解指令

指令是以v-开头的特殊属性名;

上面是一段典型的使用v-for指令的代码,你可以把class认为是div的属性,同样,也可以认为v-for是属性名

每个指令都有自己的使用格式及场景。
当现有的指令不够用时,vue允许你去拓展。

定义及使用自定义指令

官网地址

定义格式:

// 注册一个全局自定义指令 v-yourname
Vue.directive(‘yourname’, {
bind: function(el, binding, vnode){
console.log(‘bind…’)
console.dir(el)
console.dir(binding)
console.dir(vnode)
},
inserted: function(el, binding, vnode){
console.log(‘inserted…’)
console.dir(el)
console.dir(binding)
console.dir(vnode)
},
update: function(el, binding, vnode,oldVnode){
console.log(‘update…’)
console.dir(el)
console.dir(binding)
console.dir(vnode)
console.dir(oldVnode)
},
componentUpdated: function(el, binding, vnode,oldVnode){
console.log(‘componentUpdated…’)
console.dir(el)
console.dir(binding)
console.dir(vnode)
console.dir(oldVnode)
},
unbind: function (el, binding, vnode) {
console.log(‘unbind…’)
console.dir(el)
console.dir(binding)
console.dir(vnode)
}
})
各钩子函数如下:

bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新。
componentUpdated :指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind:只调用一次,指令与元素解绑时调用。
执行顺序是:

  1. 初始化 bind–>inserted
  2. 更新中 update–>componentUpdated
  3. 销毁 unbind

钩子函数会被传入以下参数

el:指令所绑定的元素,可以用来直接操作 DOM。
binding:一个对象,包含以下 property:
binding.name:指令名,不包括 v- 前缀。
value:指令的绑定值,例如:v-my-directive=“1 + 1” 中,绑定值为 2。
oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
expression:字符串形式的指令表达式。例如 v-my-directive=“1 + 1” 中,表达式为 “1 + 1”
arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 “foo”。
modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。
vnode:Vue 编译生成的虚拟节点。
oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

示例:跳动增长的数值

如下示意图。

图片
当我们显示一个数值时,我们希望它实现从0开始慢慢增长的动态效果(脑补一下你的银行卡余额的增长)

销量:

Vue.directive(‘jump’, {
// 你的代码
})

new Vue({
el: ‘#app’
data: {
num: 2000
}
})
这里简化需求:num值是正整数。

思路:通过定时器,不断增加数值,直接更新dom。

参考代码如下:

Vue.directive(‘jump’, {
inserted: function(el, binding, vnode){
// 把数值和函数挂到el上,方便在多个钩子上进行共享
el.updateF = function(){
console.log(‘updateF…’)
let start = 0;
const dt = (el.targetNum - start) / (el.totalTime/50)
el.currentNum = el.currentNum + dt
// 停止条件
if(el.currentNum > el.targetNum) {
el.currentNum = el.targetNum
clearInterval(el.timer)
}
// 更新dom
el.innerText = el.currentNum
}
el.start = function(value){
if(el.currentNum === value)
return
el.totalTime = 1000
el.currentNum = el.currentNum || 0
el.targetNum = value
el.timer = setInterval( ()=> {
el.updateF()
}, 50)
}
el.start(binding.value)
},
update: function(el, binding, vnode,oldVnode){
el.start(binding.value)
},
unbind: function (el, binding, vnode) {
// 做一些销毁工作
clearInterval(el.timer)
el.updateF = null
el.start = null
delete el.updateF
delete el.start
delete el.totalTime
delete el.currentNum
delete el.targetNum
}
})
你还可以进一步拓展: 1. 允许小数;2.允许负数;3.指定花费时长…

其它示例代码

参考别人的代码就是最好的学习方式。

在当前元素之外的点击。例如你有一个弹出层,希望捕获鼠标在页面其它地方点击(就不在弹出层上点击)的动作。来自iview,代码地址: https://github.com/iview/iview/blob/2.0/src/directives/clickoutside.js
将当前元素全屏展示。例如你有一个echart画的图表,原来是嵌入在页面中的,希望点击按钮之后,它能全局显示。我自己写的,代码地址:https://github.com/fanyoufu/vdirectives/blob/master/directives/fullScreen.js
元素拖动。允许元素进行拖动。来自iview-admin,代码地址:https://github.com/iview/iview-admin/blob/master/src/directive/module/draggable.js
其它指令。来自vue-element-admin,代码地址:https://github.com/PanJiaChen/vue-element-admin/tree/master/src/directive
小结

本文介绍了vue中自定义指令的格式及用法,并通过一个简单的有趣的例子描述了实际的应用场景,并附出一些实践的应用案例代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值