likes
comments
collection
share

《Vuejs设计与实现》8.7 事件的处理

作者站长头像
站长
· 阅读数 36

在讲完了如何区分组件之后,我们再来看看,如何区分事件,处理事件。

  • 在vue2中,事件是放在on之下的
const vnode = {
    type:'button',
    on:{
        click(){}
    }
}
  • 在vue3中,事件则同样被扁平化,我们约定以on开头的都是事件,因此结构就变成了
const vnode = {
    type:'button',
    onClick(){}
}

这样处理的原因也是能够更方便检测,减少层级,减少递归。

那么我们怎么样把事件绑定到DOM上呢,绝大多数人第一反应肯定是addEventListener,肯定是没问题的,而且性能也不错,是一个普适性比较高的方案,但其实,这里还是有很多优化的空间的。

假设我们就直接使用addEventListener,当vnode变化或者绑定的事件变化时,我们肯定需要先解绑事件,因此我们要调用removeEventListener,如果组件变化更新比较频繁,比如列表的时候,我们不停的滑动,不停的加载列表项,频繁绑定解绑事件也会造成卡顿。

解决的办法就是我们不解绑事件,我们通过响应式变量去处理,我们可以在vnode下声明一个ref,然后当绑定的事件变化时,动态改变它的value。我们假设,当props变化时,会调用patchProps,这个方法应该属于patch

我们可以在声明一个handler的匿名函数,这样我们只需要绑定一次就可以实现事件切换,因为我们每次改变的只是invoker.value即可。

const invoker = ref(null)
const handler = (evt)=>{
    if(unref(invoker)){
        invoker.value(evt)
    }
}

假设我们的事件现在解绑了,我们也只需要把invoker.value = null,这样哪怕事件还在,也不会触发事件处理函数。当然,上面只是一个伪代码,真正在使用的时候,我们还需要注意

  • 根据事件名缓存事件处理函数,也就是可能会有多个invoker,如果你只赋值一个,就会被覆盖。
  • addEventListener其实是可以当定多个事件的,比如绑定2个click事件,我觉得可以把 const invoker = ref(new Set())这样去解决,但不知道vue3是不是这样做的
转载自:https://juejin.cn/post/7137276408975327263
评论
请登录