课程章节介绍
同学们,今天我们来说一下LWC里的事件传播,这和我们熟悉的普通网页DOM事件很相似,只是多了些Web Component特有的细节。先理解两个最关键的属性:“bubbles”和“composed”。
“bubbles”就是冒泡,它决定事件会不会像水里的气泡一样,从触发元素一直向上传到它的祖先元素。比如你在一个按钮上点一下,如果事件设置了bubbles为true,那这个按钮的父元素、祖父元素、一直到根元素都能监听到。要是设为false,事件就停在原地,不向上跑。
第二个属性是“composed”,它控制事件能不能穿透“影子边界”。LWC里的每个组件都有自己的影子DOM,外面是看不到里面的。默认情况下,事件只在自己的影子DOM里冒泡,传到影子根就停了。但如果你把composed设为true,事件就能穿过这个边界,继续向上冒泡到父组件,这就让跨组件的事件通信成为可能。
要注意,LWC只支持事件传播的“冒泡阶段”,它不支持“捕获阶段”。也就是说,你没法在父元素上先用捕获的方式拦截事件,事件只能从目标元素开始一层层向上冒泡。这是LWC在性能和安全上的一个刻意设计。
了解这两个属性后,我们来看看事件处理时有三个好用的属性帮你了解传播路径。
第一个是“target”,它指向事件最初调度出来的那个元素,也就是最开始触发事件的源头。但在影子DOM里,这个target会被“重新定位”。什么意思呢?就是如果事件从组件内部的一个按钮发出,当它穿过影子边界后,在外层组件眼里,target就变成了那个自定义元素标签,比如c-child,而不是内部的button。这样保护了组件内部结构,也符合Web组件的封装原则。
第二个是“currentTarget”,它指的是当前正在处理这个事件的那个元素。随着事件向上冒泡,currentTarget会跟着变。比如你在c-parent上挂了个事件处理器,当事件冒泡到c-parent时,那个处理器里的currentTarget就是c-parent。而在子组件里,它可能是c-child。所以currentTarget答案“事件现在走到谁家了”。
第三个是“composedPath()”方法,它能返回一个完整的数组,记录了事件传播路径上所有经过的目标元素,包括那些被影子边界重新定位前的真实内部节点。这在调试时非常有用,可以看到事件到底穿过了哪些组件。
我们拿一个静态的合成示例来说明:假设有个最外层的c-app组件,里面放了c-parent组件;c-parent内部有一个div包裹着c-child组件和一个原生按钮。我们对每个级别都挂上事件监听器。用一张“扁平树”图去看,就会发现:
- 当你点按钮时,事件如果设置了bubbles true和composed true,它在c-child内部先冒泡,然后穿过c-child的影子边界,再经过包裹的div,再到c-parent,最后到达c-app。
- 在每个级别,target在组件内部可能显示具体按钮,但过了边界就显示c-child,而currentTarget跟着处理器的附着点变化。
- composedPath()把这些节点全都记录下来,你可以看到一条完整的路径。
总结一下,掌握LWC的事件传播,记住这两句口诀:bubbles管向上冒泡,composed管跨边界。只冒泡不捕获,target会重定位,currentTarget随冒泡而变,composedPath给全貌。搞懂这些,你就能轻松驾驭组件间的事件通信了。
关键词
LWC
Lightning Web Components
Salesforce