前边讲过方法【this.dispatchEvent()】的用法,可以实现父子Lwc组件之间的相互调用,今天讲解Communicate Across the DOM with Lightning Message Service,使用【Lightning message service】在Lightning页面内跨DOM进行通信,可以实现在嵌入在同一Lightning页面中的Visualforce页面,Aura组件和Lightning Web组件之间进行通信,可以不用
首先在【lwc】同级目录下,新建【messageChannels】文件夹,在里边新建【xxx.messageChannel-meta.xml】文件。
Record_Selected.messageChannel-meta.xml
<?xml version="1.0" encoding="UTF-8" ?>
<LightningMessageChannel xmlns="http://soap.sforce.com/2006/04/metadata">
<masterLabel>RecordSelected</masterLabel>
<isExposed>true</isExposed>
<description>Message Channel to pass a record Id</description>
<lightningMessageFields>
<fieldName>recordId</fieldName>
<description>This is the record Id that changed</description>
</lightningMessageFields>
</LightningMessageChannel>
在JavaScript文件中调用【publish()】函数进行消息发布,直到组件生命周期销毁为止,
·固定写法:引入【publish】,【MessageContext】
import { publish, MessageContext } from 'lightning/messageService';
·固定写法:使用【@wire(MessageContext)】创建【MessageContext】object,用以提供有关【Lightning web component】的信息
例:
import { LightningElement, wire } from 'lwc';
import getContactList from '@salesforce/apex/ContactController.getContactList';
// Import message service features required for publishing and the message channel
import { publish, MessageContext } from 'lightning/messageService';
import RECORD_SELECTED_CHANNEL from '@salesforce/messageChannel/Record_Selected__c';
export default class LmsComponent1 extends LightningElement {
@wire(getContactList)
contacts;
@wire(MessageContext)
messageContext;
// Respond to UI event by publishing message
handleContactSelect(event) {
const payload = { recordId: event.target.contact.Id };
publish(this.messageContext, RECORD_SELECTED_CHANNEL, payload);
}
}
<template>
<lightning-card
title="LmsPublisherWebComponent"
icon-name="custom:custom30"
>
<div class="slds-m-around_medium" oncontactselect={handleContactSelect}>
<template if:true={contacts.data}>
<template for:each={contacts.data} for:item="contact">
<c-contact-list-item-bubbling
key={contact.Id}
contact={contact}
></c-contact-list-item-bubbling>
</template>
</template>
</div>
</lightning-card>
</template>
子Component
contactListItemBubbling.js
import { LightningElement, api } from 'lwc';
export default class ContactListItemBubbling extends LightningElement {
@api contact;
handleSelect(event) {
event.preventDefault();
const selectEvent = new CustomEvent('contactselect', {
bubbles: true
});
this.dispatchEvent(selectEvent);
}
}
contactListItemBubbling.html
<template>
<a href="#" onclick={handleSelect}>
<lightning-layout vertical-align="center">
<lightning-layout-item>
<img src={contact.Picture__c} alt="Profile photo" />
</lightning-layout-item>
<lightning-layout-item padding="around-small">
<p>{contact.Name}</p>
</lightning-layout-item>
</lightning-layout>
</a>
</template>
contactListItemBubbling.css
img {
width: 30px;
height: 30px;
border-radius: 50%;
}
接受消息调用【subscribe】函数,
·固定写法:引入
import { subscribe, MessageContext } from 'lightning/messageService';
·固定写法:同上,使用【@wire(MessageContext)】创建【MessageContext】object,用以提供有关【Lightning web component】的信息
·在初期化方法中调用【subscribe】函数,取得传过来的参数【RecordId】
例:
import { LightningElement, wire } from 'lwc';
import { getRecord, getFieldValue } from 'lightning/uiRecordApi';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { reduceErrors } from 'c/ldsUtils';
import { subscribe, MessageContext } from 'lightning/messageService';
import RECORD_SELECTED_CHANNEL from '@salesforce/messageChannel/Record_Selected__c';
import NAME_FIELD from '@salesforce/schema/Contact.Name';
import TITLE_FIELD from '@salesforce/schema/Contact.Title';
import PHONE_FIELD from '@salesforce/schema/Contact.Phone';
import EMAIL_FIELD from '@salesforce/schema/Contact.Email';
import PICTURE_FIELD from '@salesforce/schema/Contact.Picture__c';
const fields = [
NAME_FIELD,
TITLE_FIELD,
PHONE_FIELD,
EMAIL_FIELD,
PICTURE_FIELD
];
export default class LmsComponent2 extends LightningElement {
subscription = null;
recordId;
Name;
Title;
Phone;
Email;
Picture__c;
@wire(getRecord, { recordId: '$recordId', fields })
wiredRecord({ error, data }) {
if (error) {
this.dispatchToast(error);
} else if (data) {
fields.forEach(
(item) => (this[item.fieldApiName] = getFieldValue(data, item))
);
}
}
// By using the MessageContext @wire adapter, unsubscribe will be called
// implicitly during the component descruction lifecycle.
@wire(MessageContext)
messageContext;
// Encapsulate logic for LMS subscribe.
subscribeToMessageChannel() {
this.subscription = subscribe(
this.messageContext,
RECORD_SELECTED_CHANNEL,
(message) => this.handleMessage(message)
);
}
// Handler for message received by component
handleMessage(message) {
this.recordId = message.recordId;
}
// Standard lifecycle hooks used to sub/unsub to message channel
connectedCallback() {
this.subscribeToMessageChannel();
}
// Helper
dispatchToast(error) {
this.dispatchEvent(
new ShowToastEvent({
title: 'Error loading contact',
message: reduceErrors(error).join(', '),
variant: 'error'
})
);
}
}
<template>
<lightning-card
title="LmsSubscriberWebComponent"
icon-name="custom:custom30"
>
<div class="slds-m-around_medium">
<template if:true={Picture__c}>
<img src={Picture__c} alt="Profile photo" />
</template>
<p>{Name}</p>
<p>{Title}</p>
<p>
<lightning-formatted-phone
value={Phone}
></lightning-formatted-phone>
</p>
<p>
<lightning-formatted-email
value={Email}
></lightning-formatted-email>
</p>
</div>
</lightning-card>
</template>
css
img {
width: 80px;
height: 80px;
border-radius: 50%;
margin-bottom: 8px;
}
效果展示:
把两个组件拖到不同位置,点击List上的一条数据,通过【Lightning message service】传递RecordId,用以展示详细信息。
可以自己设置接收范围,接收范围包括:
例:
// Import message service features.
import {
subscribe,
unsubscribe,
APPLICATION_SCOPE,
MessageContext
} from 'lightning/messageService';
// To pass scope, you must get a message context.
@wire(MessageContext)
messageContext;
// Pass scope to the subscribe() method.
subscribeToMessageChannel() {
if (!this.subscription) {
this.subscription = subscribe(
this.messageContext,
recordSelected,
(message) => this.handleMessage(message),
{ scope: APPLICATION_SCOPE }
);
}
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。