LWC组件直接的通信第三种类型:非父子关系。LWC使用LMS(闪电消息服务)消息发布与订阅服务,实现跨 DOM 的子树之间的通信
创建消息通道
- 新建文件夹与LWC同级:
messageChannels - 在 messageChannels 文件夹下,新建文件:
Count_Updated.messageChannel-meta.xml - 替换以下代码:
<?xml version="1.0" encoding="UTF-8" ?>
<LightningMessageChannel xmlns="http://soap.sforce.com/2006/04/metadata">
<masterLabel>CountUpdated</masterLabel>
<isExposed>true</isExposed>
<description>这是一个消息通道,名为CountUpdated,引用的时候为Count_Updated__c</description>
<lightningMessageFields>
<fieldName>operator</fieldName>
<description>This is the operator type of the manipulation</description>
</lightningMessageFields>
<lightningMessageFields>
<fieldName>constant</fieldName>
<description>This is the number for the manipulation</description>
</lightningMessageFields>
</LightningMessageChannel>
创建发布者组件
- 新建LWC:
remoteControl - remoteControl.js
import { publish, MessageContext } from 'lightning/messageService';
import { LightningElement, wire } from 'lwc';
import COUNT_UPDATED_CHANNEL from '@salesforce/messageChannel/Count_Updated__c';
export default class RemoteControl extends LightningElement {
@wire(MessageContext)
messageContext;
handleIncrement() {
// this.counter++;
const payload = {
operator: 'add',
constant: 1
};
publish(this.messageContext, COUNT_UPDATED_CHANNEL, payload);
}
handleDecrement() {
// this.counter--;
const payload = {
operator: 'subtract',
constant: 1
};
publish(this.messageContext, COUNT_UPDATED_CHANNEL, payload);
}
handleMultiply(event) {
const factor = event.detail;
// this.counter *= factor;
const payload = {
operator: 'multiply',
constant: factor
};
publish(this.messageContext, COUNT_UPDATED_CHANNEL, payload);
}
}
- remoteControl.htm
<template>
<lightning-card title="Remote Control" icon-name="action:change_record_type">
<c-controls class="slds-show slds-is-relative" onadd={handleIncrement} onsubtract={handleDecrement}
onmultiply={handleMultiply}>
</c-controls>
</lightning-card>
</template>
controls 组件在上两篇文章中已创建
- remoteControl.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>55.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
</targets>
</LightningComponentBundle>
创建订阅者组件
- 新建LWC:
counts - counts.js
import { subscribe, MessageContext, unsubscribe } from 'lightning/messageService';
import { LightningElement, wire } from 'lwc';
import COUNT_UPDATED_CHANNEL from '@salesforce/messageChannel/Count_Updated__c';
export default class Counts extends LightningElement {
subscription = null;
priorCount = 0;
counter = 0;
@wire(MessageContext)
messageContext;
subscribeToMessageChannel() {
this.subscription = subscribe(
this.messageContext,
COUNT_UPDATED_CHANNEL,
(message) => this.handleMessage(message)
);
}
unsubscribeToMessageChannel() {
unsubscribe(this.subscription);
this.subscription = null;
}
handleMessage(message) {
this.priorCount = this.counter;
if (message.operator == 'add') {
this.counter += message.constant;
} else if (message.operator == 'subtract') {
this.counter -= message.constant;
} else {
this.counter *= message.constant;
}
}
connectedCallback() {
this.subscribeToMessageChannel();
}
disconnectedCallback() {
this.unsubscribeToMessageChannel();
}
}
- counts.html
<template>
<lightning-card title="Counts" icon-name="action:change_record_type">
<p class="slds-text-align_center slds-var-m-vertical_medium">
Prior Count: <lightning-formatted-number value={priorCount}></lightning-formatted-number>
</p>
<p class="slds-text-align_center slds-var-m-vertical_medium">
Count: <lightning-formatted-number value={counter}></lightning-formatted-number>
</p>
</lightning-card>
</template>
- counts.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>55.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
</targets>
</LightningComponentBundle>
当点击 Add 按钮时,remoteControl 组件发布消息
{ operator: 'add', constant: 1 },counts 组件订阅该消息:subscribe(this.messageContext, COUNT_UPDATED_CHANNEL, (message) => {});