一、从子组件到父组件通信
当子组件需要告诉父组件某件事时,它用标准 DOM CustomEvents。本单元创建并派发带数据负载的事件,用关键的 bubbles:true 和 composed:true 标志让事件沿组件层级向上传播——甚至穿越 Shadow DOM 边界。
用 Custom Events 从子到父
子组件——创建并派发 CustomEvent:
handleClick() {
const event = new CustomEvent('itemselected', {
detail: { id: this.itemId, name: this.itemName }
});
this.dispatchEvent(event);
}
父组件——监听并处理:模板 <c-child onitemselected={handleItemSelected}>,JS handleItemSelected(event) { const { id, name } = event.detail; }。
让事件冒泡穿过层级:无标志时只有直接父组件能听到事件(Shadow DOM 边界阻止传播);bubbles: true 让事件沿 DOM 树向上传播;composed: true 让事件穿越 Shadow DOM 边界(LWC 每个组件有自己的 Shadow DOM,没有 composed:true 事件会被困住);两者都设时,孙组件的事件能被任何祖先听到。
关键原则:让事件尽可能局部——只有直接父组件需要就开冒泡,只有直接父组件之上的祖先真正需要才设 composed:true。
二、从父组件到子组件通信
父到子通信用 @api——把属性和方法暴露为公共的装饰器。覆盖三种模式:从 HTML 响应式设置公共属性、从 JavaScript 命令式调用公共方法、用 getter/setter 拦截并响应属性变化。
父到子——三种 @api 模式
1. 更新公共属性——响应式,最常见:子组件 @api itemName;、@api quantity = 0;;父模板 <c-order-item item-name={product.name} quantity={product.qty}>——product.name 变化时子组件自动收到新值,响应式、无需代码。
2. 调用公共函数——命令式控制:子组件 @api reset() { this.quantity = 0; };父 JS this.template.querySelector('c-order-item').reset()。用于验证、重置、聚焦、刷新——父组件需要触发的动作而非传递的数据。
3. Getter 和 Setter——拦截属性变化:@api get itemName() { return this._itemName; } set itemName(value) { this._itemName = value; this.validate(); }。用于需要验证、转换、或响应属性变化的业务逻辑。
默认值来自 JavaScript,而非父组件——父组件只在显式传值时覆盖。
三、无关联组件之间的通信
组件没有父子关系时怎么办?Lightning Message Service 提供发布-订阅模式,通过元数据定义的命名消息通道连接任意组件到任意组件——不同 App Builder 区域、不同 DOM 子树、甚至不同浏览器标签。
Lightning Message Service——完整模式
LMS 连接没有共享父组件的组件——不同 App Builder 插槽、不同标签、不同窗口。
1. 消息通道(元数据 XML):定义在 messageChannels/ 目录,含 <LightningMessageChannel>、<isExposed>true</isExposed>、<lightningMessageFields>(字段名)。
2. 发布者:import { publish, MessageContext } from 'lightning/messageService'、@wire(MessageContext) messageContext,然后 publish(this.messageContext, Count_Updated, { operator: 'add', constant: 5 })。
3. 订阅者:import { subscribe, MessageContext }、this.subscription = subscribe(this.messageContext, Count_Updated, (message) => this.handleMessage(message))。
何时选 LMS vs DOM 事件:DOM CustomEvents → 父子关系,更高效,优先用;LMS → 无关联组件、不同子树、LWC 到 Aura 桥接、多标签同步(也兼容 Visualforce 页面)。别过度用 LMS——DOM 事件更快更简单且无需 XML 文件,LMS 是组件真正没有共同祖先时的逃生舱。

文章来源:Trailhead - Communicate Between Lightning Web Components





