Salesforce LWC 组件间通信

Salesforce LWC 组件间通信

LWC组件间通信,通常是父子组件通信和非父子组件通信,一般有三种场景:

  • 父组件向子组件传递值。一般在子组件的变量或方法使用@api注解,由父组件向@api公开的变量传递值,或调用子组件方法。
  • 子组件向父组件传递值。一般使用CustomEvent,子组件通过dispatchEvent发出一个事件,由父组件监听。
  • 非父子组件传递值。一般使用LMS(Lightning Message Service),这是一种发布订阅模式,由发布者发布event,再由订阅者订阅,接收payload。

一、父子组件传值

1.1 父组件向子组件传递值

第一,子组件中使用@api公开变量(方法)即可。

sonLwc.js

scala 复制代码
 import { LightningElement, api } from 'lwc';
 import LightningAlert from 'lightning/alert';
 ​
 export default class SonLwc extends LightningElement {
     @api itemName = 'Test';
 ​
     @api alertItemNameInfo() {
         LightningAlert.open({
             message: this.itemName,
             theme: 'info'
         });
     }
 }

第二,父组件调用子组件,通过c-的方式引用子组件,公开的变量也使用同样的方式去传递值。

parentLwc.html

xml 复制代码
 <template>
     <lightning-card title="Parent LWC" icon-name="custom:custom63">
         <div>
             <div>
                 <span>send parent data to son lwc</span>
                 <!-- 引用子组件,名字首字母前加上了 c加上破折号(-),api公开的变量同样。c是默认的命名空间 -->
                 <c-son-lwc item-name={sonItemName}></c-son-lwc>
                 <lightning-button label="alert item info" onclick={handleAlertItemNameEvent}></lightning-button>
             </div>
         </div>
     </lightning-card>
 </template>

parentLwc.js

scala 复制代码
import { LightningElement, api, track, wire } from 'lwc';

export default class ParentLwc extends LightningElement {
    sonItemName = 'test parent for son item';

	handleAlertItemNameEvent() {
		this.template.querySelector('c-son-lwc').alertItemNameInfo();
	}
}

这里使用了button去触发子组件方法,方法中弹出了当前子组件itemName的值,点击后可以观察到,子组件值已被父组件覆盖。说明父组件已经将值传递给子组件,并且也能够触发子组件方法。

1.2 子组件向父组件传递值

第一,子组件需要通过CustomEvent的方式去发出一个事件,由父组件监听。可以使用一个button来做触发动作。

sonLwc.html

xml 复制代码
<template>
    <lightning-button label="send data to parent lwc" onclick={handleSendData}></lightning-button>
</template>

sonLwc.js

scala 复制代码
import { LightningElement, api } from 'lwc';
import LightningAlert from 'lightning/alert';

export default class SonLwc extends LightningElement {
    itemValue = "Hello from Son Component";

    handleSendData() {
        const customEvent = new CustomEvent("senddata", {
            detail: {
                message: this.itemValue,
            }
        });
        this.dispatchEvent(customEvent); // 主要功能是将一个事件对象分发到指定的 DOM 元素上,从而触发该元素上绑定的事件监听器
    }
}

CustomEvent构造时,name建议全小写,detail中可以设这么用于传递的数据。还有诸如bubblescomposed等参数可以设定。请参考Events Best Practices

第二,父组件通过on-eventname监听事件,并从中取到子组件传递的数据。

parentLwc.html

xml 复制代码
 <template>
     <lightning-card title="Parent LWC" icon-name="custom:custom63">
         <div>
             <div>
                 <span>send parent data to son lwc</span>
                 <!-- 引用子组件,名字首字母前加上了 c加上破折号(-),api公开的变量同样。c是默认的命名空间 -->
                 <c-son-lwc onsenddata={handleDataReceived}></c-son-lwc>
                 <p>Data received from Son Component: {receivedMessage}</p>
             </div>
         </div>
     </lightning-card>
 </template>

parentLwc.js

scala 复制代码
 import { LightningElement, api, track, wire } from 'lwc';
 ​
 export default class ParentLwc extends LightningElement {
     receivedMessage;
 ​
     handleDataReceived(event) {
         this.receivedMessage = event.detail.message;
     }
 }

通过点击button,就可以看到子组件的值会传递给父组件。

二、非父子组件传值

对于非父子组件传值,Salesforce提供了Lightning Message Service的标准方法去实现。LMS可以实现LWC,Aura,Visualforce Page之间的跨组件通信。

第一步,需要先创建messageChannels,messageChannels只能通过metadata的方式创建。

xml 复制代码
 <?xml version="1.0" encoding="UTF-8"?>
 <LightningMessageChannel xmlns="http://soap.sforce.com/2006/04/metadata">
     <description>Message Channel to pass a field value</description>
     <isExposed>true</isExposed>
     <masterLabel>FieldValueTransfer</masterLabel>
 </LightningMessageChannel>

第二步,创建publisher组件

publisherLwc.html

xml 复制代码
 <template>
     <lightning-card title="Publisher Component" icon-name="custom:custom63">
         <div class="slds-m-around_medium">
             <lightning-input label="Enter Message" value={messageText} onchange={handleInputChange}></lightning-input>
             <lightning-button label="Send Message" onclick={handleSend}></lightning-button>
         </div>
     </lightning-card>
 </template>

publishLwc.js

typescript 复制代码
 import { LightningElement, api, track, wire } from 'lwc';
 import { publish, MessageContext } from 'lightning/messageService';
 import MY_MESSAGE_CHANNEL from '@salesforce/messageChannel/FieldValueTransfer__c';
 ​
 export default class PublisherComponent extends LightningElement {
     messageText = '';
 ​
     @wire(MessageContext)
     messageContext;
 ​
     handleInputChange(event) {
         this.messageText = event.target.value;
     }
 ​
     handleSend() {
         const message = { data: this.messageText};
         publish(this.messageContext, MY_MESSAGE_CHANNEL, message);
     }
 }

第三步,创建subscriber组件

subscriberLwc.html

xml 复制代码
 <template>
     <lightning-card title="Subscriber Component" icon-name="custom:custom63">
         <div class="slds-m-around_medium">
             <p>Received Message: {receivedMessage}</p>
         </div>
     </lightning-card>
 </template>

subscriberLwc.js

typescript 复制代码
 import { LightningElement, wire } from 'lwc';
 import { subscribe, MessageContext } from 'lightning/messageService';
 import MY_MESSAGE_CHANNEL from '@salesforce/messageChannel/FieldValueTransfer__c';
 ​
 export default class SubscriberComponent extends LightningElement {
     subscription = null;
     receivedMessage = '';
 ​
     @wire(MessageContext)
     messageContext;
 ​
     connectedCallback() {
         this.subscribeToMessageChannel();
     }
 ​
     subscribeToMessageChannel() {
         if (this.subscription) {
             return;
         }
         this.subscription = subscribe(this.messageContext, MY_MESSAGE_CHANNEL, (message) => {
             this.handleMessage(message);
         });
     }
 ​
     handleMessage(message) {
         this.receivedMessage = message.data;
     }
 }

将publisher和subscriber放到同一个lightning page,就可以观察到效果。由publisher发送一条数据,subscriber就可以接收到这条数据。

关于LMS的更多内容,请见lightning-message-service

相关推荐
YGGP15 分钟前
【每日八股】Golang篇(二):关键字(上)
开发语言·后端·golang
无奈何杨28 分钟前
阿里TTL+Log4j2+MDC实现轻量级日志链路追踪
后端
伯牙碎琴29 分钟前
十一、Spring Boot:使用JWT实现用户认证深度解析
java·spring boot·后端
何中应1 小时前
你为什么要写博客?
java·后端·程序员创富
utmhikari4 小时前
【架构艺术】Go语言微服务monorepo的代码架构设计
后端·微服务·架构·golang·monorepo
蜡笔小新星4 小时前
Flask项目框架
开发语言·前端·经验分享·后端·python·学习·flask
计算机学姐4 小时前
基于Asp.net的驾校管理系统
vue.js·后端·mysql·sqlserver·c#·asp.net·.netcore
欢乐少年19046 小时前
SpringBoot集成Sentry日志收集-3 (Spring Boot集成)
spring boot·后端·sentry
浪九天9 小时前
Java直通车系列13【Spring MVC】(Spring MVC常用注解)
java·后端·spring
uhakadotcom10 小时前
Apache CXF 中的拒绝服务漏洞 CVE-2025-23184 详解
后端·面试·github