vue源码解析:vue事件方法之$once方法的实现原理
vue中事件方法一共就四个,挂载在vue实例上的$once用来监听某个自定义事件,通常会用到,那么$once的内部实现原理是什么呢?下面我们来详细说下$once:参数:{string} event{Function} callback作用:监听一个自定义事件,但是只触发一次。一旦触发之后,监听器就会被移除。原理:Vue.prototype.$once = function (event, fn)
vue中事件方法一共就四个,挂载在vue实例上的$once用来监听某个自定义事件,通常会用到,那么$once的内部实现原理是什么呢?下面我们来详细说下$once:
参数:
{string} event
{Function} callback
作用:
监听一个自定义事件,但是只触发一次。一旦触发之后,监听器就会被移除。
原理:
Vue.prototype.$once = function (event, fn) {
const vm: Component = this
function on () {
vm.$off(event, on)
fn.apply(vm, arguments)
}
on.fn = fn
vm.$on(event, on)
return vm
}
我们可以看到$once函数的逻辑其实很简单,在函数的内部声明了一个on函数,on函数里面第一步移除传入的事件,第二部执行回掉,所以当订阅$on事件的时候,此时执行的就是on方法,这样就实现了事件执行一次后直接将事件删除的功能。但是你会发现有一行代码on.fn = fn,这是什么操作呢?我们用子函数on
替换了原本的订阅事件所对应的回调fn
,那么在事件中心_events
属性中存储的该事件名就会变成如下这个样子:
vm._events = {
'xxx':[on]
}
但是用户自己却不知道传入的fn
被替换了,当用户在触发该事件之前想调用$off
方法移除该事件时:
vm.$off('xxx',fn)
此时就会出现问题,因为在_events
属性中的事件名xxx
对应的回调函数列表中没有fn
,那么就会移除失败。这就让用户费解了,用户明明给xxx
事件传入的回调函数是fn
,现在反而找不到fn
导致事件移除不了了。
所以,为了解决这一问题,我们需要给on
上绑定一个fn
属性,属性值为用户传入的回调fn
,这样在使用$off
移除事件的时候,$off
内部会判断如果回调函数列表中某一项的fn
属性与fn
相同时,就可以成功移除事件了。
这就是vue的$once方法的原理。
更多推荐
所有评论(0)