第 8 章 挂载与更新(2)
霍春阳(HcySunYang)
8.7 事件的处理
本节我们将讨论如何处理事件,包括如何在虚拟节点中描述事件,如何把事件添加到 DOM 元素上,以及如何更新事件。
我们先来解决第一个问题,即如何在虚拟节点中描述事件。事件可以视作一种特殊的属性,因此我们可以约定,在 vnode.props 对象中,凡是以字符串 on 开头的属性都视作事件。例如:
解决了事件在虚拟节点层面的描述问题后,我们再来看看如何将事件添加到 DOM 元素上。这非常简单,只需要在 patchProps 中调用 addEventListener 函数来绑定事件即可,如下面的代码所示:
那么,更新事件要如何处理呢?按照一般的思路,我们需要先移除之前添加的事件处理函数,然后再将新的事件处理函数绑定到 DOM 元素上,如下面的代码所示:
这么做代码能够按照预期工作,但其实还有一种性能更优的方式来完成事件更新。在绑定事件时,我们可以绑定一个伪造的事件处理函数 invoker,然后把真正的事件处理函数设置为 invoker.value 属性的值。这样当更新事件的时候,我们将不再需要调用 removeEventListener 函数来移除上一次绑定的事件,只需要更新 invoker.value 的值即可,如下面的代码所示:
观察上面的代码,事件绑定主要分为两个步骤。
先从 el._vei 中读取对应的 invoker,如果 invoker 不存在,则将伪造的 invoker 作为事件处理函数,并将它缓存到 el._vei 属性中。
把真正的事件处理函数赋值给 invoker.value 属性,然后把伪造的 invoker 函数作为事件处理函数绑定到元素上。可以看到,当事件触发时,实际上执行的是伪造的事件处理函数,在其内部间接执行了真正的事件处理函数 invoker.value(e)。
当更新事件时,由于 el._vei 已经存在了,所以我们只需要将 invoker.value 的值修改为新的事件处理函数即可。这样,在更新事件时可以避免一次 removeEventListener 函数的调用,从而提升了性能。实际上,伪造的事件处理函数的作用不止于此,它还能解决事件冒泡与事件更新之间相互影响的问题,下文会详细讲解。
公开
同步至部落
取消
完成
0/2000
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
![](https://static001.geekbang.org/resource/image/d0/e4/d0880927e2a522a038be2d04bf19dfe4.png)
本文深入探讨了虚拟节点中描述事件、添加到 DOM 元素以及更新事件的方法。作者介绍了描述事件的方式,并详细介绍了如何将事件添加到 DOM 元素,提出了一种性能更优的方式来更新事件。同时,作者指出了当前实现存在的问题,并提出了解决方案。文章还介绍了如何描述同一类型事件的多个事件处理函数。通过讨论事件冒泡与更新时机相结合所导致的问题,以及解决方案,文章深入浅出地介绍了事件处理的相关技术细节。读者可以从中快速了解事件处理的核心问题和解决方案。文章还讨论了文本节点和注释节点的描述方法。文章内容涵盖了虚拟节点中事件处理和节点描述的技术细节,适合想要深入了解前端开发技术的读者阅读。此外,还介绍了新的虚拟节点类型——Fragment,以及如何使用Fragment来描述多根节点模板,为读者提供了更多关于Vue.js 3的相关知识。文章内容丰富,涵盖了前端开发中的重要技术细节,对于想要深入了解虚拟节点和事件处理的读者来说,是一篇值得阅读的文章。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Vue.js 设计与实现》
《Vue.js 设计与实现》
立即购买
登录 后留言
精选留言
由作者筛选后的优质留言将会公开显示,欢迎踊跃留言。
收起评论