课程章节介绍
同学们好,今天我们聊一聊在 Lightning Web Components 里处理事件的最佳实践。这个 Slide 把要点分成了两块,一块是自定义事件的“详细信息”,也就是 details;另一块是事件传播的配置。我们先看第一块。
想象一下,同一个组件内部的元素之间传信儿,就像你们在同一个教室说悄悄话,根本不需要写条子。这时候,你完全可以跳过 details 这个字段,直接用 event.target 拿到触发事件的元素,然后读它上面的属性。比如说 event.target.myProperty,对方想传什么值,直接挂在自己身上就行了,你从它身上一读就有。为什么这么简单?因为在同一个影子树内,event.target 还是那个真实的源头,没有变化。
那什么时候才需要用到 details 呢?是当你穿过了影子边界,也就是从一个组件穿越到另一个不相关的组件时。因为这时候浏览器为了保护封装,会把 event.target 重新指向到外层的元素,真实的发起者你就拿不到了。所以只能靠 details 把数据打包递过去。记住,只要跨了影子边界,就用 details。
好,如果你要用 details,有一条铁律:永远只传原始类型的数据,像字符串、数字、布尔这些。千万别把对象或者数组原样丢进去,因为传对象传的是引用,接收方万一改动了,你的源数据也跟着变了,这就是基于引用的变异,非常难排查。所以,如果你需要传复杂数据,先把它浅拷贝一份再放进去。尤其是那些带有 @api 或 @wire 反应式的属性,它们本身是只读代理对象,直接传可能出问题,复制一下最安全。
接下来看事件传播这一块。同学们,默认值是最好的朋友——bubble 设为 false,composed 也设为 false。这意味着你的事件只会在自己的组件里冒泡,不会穿过影子根到外面去。这样最好,因为保持了封装,外面的人不用管你内部怎么实现,你的事件就是自己用的,不是公共 API。
尽量别用组合事件,也就是 composed: true。为什么呢?因为它会让事件穿透多个影子边界,一路往上冒泡,等于你无意中向外界暴露了一大片契约。如果一定要用,千万记得给事件类型加上命名空间前缀,比如 myapp__myevent,保证全局唯一,避免和其他组件的事件名冲突。
最后,所有这一切的背后都有一个基本模式:数据向下流,事件向上走。父组件通过属性把数据传给孩子,孩子有变化需要通知父级,就用事件往上抛。这样单向的数据流既清晰又可控。
总结一下:内部通信直接读属性,不要 details;跨影子边界才用 details,并且只传原始值;事件默认不冒泡不合成为好,保持封装;实在需要合成事件,加命名空间;永远遵循“属性下传,事件上传”的原则。这些最佳实践,能让你的组件更健壮,少踩坑。
好了,今天就到这里,有疑问我们随时讨论。
关键词
LWC
Lightning Web Components
Salesforce