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

相关推荐
sco52824 小时前
SpringBoot 自动装配原理 & 自定义一个 starter
java·spring boot·后端
海风极客5 小时前
《Go小技巧&易错点100例》第三十三篇
开发语言·后端·golang
养军博客5 小时前
Spring boot 简单开发接口
java·spring boot·后端
计算机学姐7 小时前
基于SpringBoot的在线教育管理系统
java·vue.js·spring boot·后端·mysql·spring·mybatis
有梦想的攻城狮8 小时前
spring中的@Value注解详解
java·后端·spring·value注解
编程乐趣9 小时前
基于.Net Core开发的GraphQL开源项目
后端·.netcore·graphql
阿乾之铭9 小时前
Spring Boot 中的重试机制
java·spring boot·后端
LUCIAZZZ10 小时前
JVM之内存管理(二)
java·jvm·后端·spring·操作系统·springboot
海风极客11 小时前
《Go小技巧&易错点100例》第三十一篇
开发语言·后端·golang
бесплатно11 小时前
Scala流程控制
开发语言·后端·scala