目次
はじめに
みなさん、Lightning Web Component(以下、LWC)で開発はしていますでしょうか?
私はテラスカイに入社してから毎日のようにLWCで開発しています。
さっそくですが、今回はLWC間の通信方法について紹介してみようと思います。
この記事でLWC間の通信方法の参考になれば幸いです。
私はテラスカイに入社してから毎日のようにLWCで開発しています。
さっそくですが、今回はLWC間の通信方法について紹介してみようと思います。
この記事でLWC間の通信方法の参考になれば幸いです。
Lightning Web Component間の通信方法について
LWC間の主な3種類の通信方法についてご紹介します。
1.publicプロパティ、publicメソッド
2.カスタムイベント
3.Lightning Message Service
1.publicプロパティ、publicメソッド
2.カスタムイベント
3.Lightning Message Service
publicプロパティ、publicメソッド
publicプロパティ、publicメソッドは親コンポーネントから子コンポーネントへ値を渡す方法になります。
親コンポーネントから@apiデコレーターを使用して、子コンポーネントへ値を直接渡します。
下記の例では、親コンポーネントで選択された値を、publicプロパティもしくは、publicメソッドを使用して値を連携し、子コンポーネント側で画面表示をします。
親コンポーネントから@apiデコレーターを使用して、子コンポーネントへ値を直接渡します。
下記の例では、親コンポーネントで選択された値を、publicプロパティもしくは、publicメソッドを使用して値を連携し、子コンポーネント側で画面表示をします。
publicプロパティ
親コンポーネント
<template> <lightning-card title="Parent"> <div class="slds-grid"> <div class="slds-p-around_medium"> <lightning-combobox name="value" label="value" value={value} options={options} onchange={handleChange} variant="label-hidden"> </lightning-combobox> </div> <div class="slds-p-around_medium"> <c-public-child value={value}></c-public-child> </div> </div> </lightning-card> </template>
publicParent.html
import { LightningElement } from 'lwc'; export default class PublicParent extends LightningElement { value = ''; get options() { return [ { label: '', value: '' }, { label: 'A', value: 'A' }, { label: 'B', value: 'B' }, { label: 'C', value: 'C' } ]; } handleChange(event) { this.value = event.detail.value; } }
publicParent.js
子コンポーネント
<template> <!-- 親から渡された値を表示する --> <div> <span>通信値 {value}</span> </div> </template>
pulicChild.html
import { LightningElement, api } from 'lwc'; export default class PublicChild extends LightningElement { // publicプロパティは@apiデコレーターを使用して宣言します。 // @apiをつけることで親コンポーネントからアクセス可能になります。 @api value; }
publicChild.js
publicメソッド
publicメソッドを使用してpublicプロパティと同様な実装すると下記のようになります。
querySelectorメソッドで子コンポーネントを取得し、メソッドを呼び出します。
querySelectorメソッドで子コンポーネントを取得し、メソッドを呼び出します。
親コンポーネント
<template> <lightning-card title="Parent"> <div class="slds-grid"> <div class="slds-p-around_medium"> <lightning-combobox name="value" label="value" value={value} options={options} onchange={handleChange} variant="label-hidden"> </lightning-combobox> </div> <div class="slds-p-around_medium"> <c-public-child></c-public-child> </div> </div> </lightning-card> </template>
publicParent.html
import { LightningElement } from 'lwc'; export default class PublicParent extends LightningElement { value = ''; get options() { return [ { label: '', value: '' }, { label: 'A', value: 'A' }, { label: 'B', value: 'B' }, { label: 'C', value: 'C' } ]; } handleChange(event) { this.value = event.detail.value; // querySelectorメソッドで子コンポーネントを取得し、publicメソッドを呼び出します。 this.template.querySelector('c-public-method-child').selectValue(this.value); } }
publicParent.js
子コンポーネント
import { LightningElement, api } from 'lwc'; export default class PublicMethodChild extends LightningElement { // publicメソッドは@apiデコレーターを使用して宣言します。 // @apiをつけることで親コンポーネントからアクセス可能になります。 value; @api selectValue(value) { this.value = value; } }
publicChild.js
カスタムイベント
カスタムイベントは子コンポーネントから親コンポーネントに値を渡す方法になります。
子コンポーネントでカスタムイベントをディスパッチし、親コンポーネントのイベントハンドラーで処理を実行します。
下記の例では、子コンポーネントをクリックした際に、カスタムイベントをディスパッチして、親コンポーネントにイベント名の値を連携し、親コンポーネント側で画面表示をします。
子コンポーネントでカスタムイベントをディスパッチし、親コンポーネントのイベントハンドラーで処理を実行します。
下記の例では、子コンポーネントをクリックした際に、カスタムイベントをディスパッチして、親コンポーネントにイベント名の値を連携し、親コンポーネント側で画面表示をします。
親コンポーネント
<template> <lightning-card title="Parent"> <p class="slds-align_absolute-center slds-text-heading_large"> <span>選択した子コンポーネントイベント: {selectValue}</span> </p> <div class="slds-m-top_xx-large slds-align_absolute-center"> <!-- on「カスタムイベント名」で、カスタムイベントのリスナーを宣言します。 ここでは「handleSelect」がリスナーとして宣言されています。 --> <c-custom-child value="イベント A" onselect={handleSelect} class="slds-m-horizontal_small"> </c-custom-child> <c-custom-child value="イベント B" onselect={handleSelect} class="slds-m-horizontal_small"> </c-custom-child> <c-custom-child value="イベント C" onselect={handleSelect} class="slds-m-horizontal_small"> </c-custom-child> </div> </lightning-card> </template>
customParent.html
import { LightningElement } from 'lwc'; export default class CustomParent extends LightningElement { selectValue = ''; // カスタムイベント発火時にhandleSelectメソッドで処理します。 // 子コンポーネントの値は「event.detail.value」で取り出すことができます。 handleSelect(event) { this.selectValue = event.detail.value; } }
customParent.js
子コンポーネント
<template> <!-- 子コンポーネントをクリックしたときにhandleClickメソッドを実行します。 --> <a onclick={handleClick}> <div class="sample"> <span>{value}</span> </div> </a> </template>
customChild.html
import { LightningElement, api } from 'lwc'; export default class CustomChild extends LightningElement { @api value = ''; // dispatchEventメソッドでカスタムイベントをディスパッチし、親コンポーネントにイベントを送信する。 handleClick() { const selectEvent = new CustomEvent('select', { detail: { value: this.value } }); this.dispatchEvent(selectEvent); } }
customChild.js
LWCでイベント通信を行うとき、通常は1つ上のコンポーネントまでしかイベント通信ができません。
しかし、2つ上の階層(またはそれ以上)にあるコンポーネントにはイベント作成時にbubbles: true, composed: trueとすることでイベント通信することが可能になります。
しかし、2つ上の階層(またはそれ以上)にあるコンポーネントにはイベント作成時にbubbles: true, composed: trueとすることでイベント通信することが可能になります。
import { LightningElement, api } from 'lwc'; export default class CustomChild extends LightningElement { @api value = ''; // dispatchEventメソッドでカスタムイベントをディスパッチし、2つ上の階層(またはそれ以上)のコンポーネントにイベントを送信可能とする。 handleClick() { const selectEvent = new CustomEvent('select', { detail: { value: this.value }, bubbles: true, composed: true }); this.dispatchEvent(selectEvent); } }
customChild.js
Lightning Message Service
階層関係(親子関係)にないコンポーネントへの通信にはLightning Message Service(以下、LMS)を使用します。LMSはLWCだけではなく、VisualforceやAuraでも使用することができます。
LMSを使用するには以下が必要になります。
1.MessageChannel(メタデータ)の作成
2.受取側のコンポーネントでメッセージチャネルをインポートして、購読(Subscribe)する
3.送信側のコンポーネントでメッセージチャネルをインポートして、送信したいデータを公開(Publish)する
※公開(Publish)を実行すると、購読(Subscribe)したすべてのコンポーネントにデータが送信されます。
下記の例では、Publishコンポーネントで選択した値をLMSで公開(Publish)します。SubscribeコンポーネントはLMSを購読(Subscribe)し、Publishコンポーネントで公開(Publish)された値を画面表示します。
LMSを使用するには以下が必要になります。
1.MessageChannel(メタデータ)の作成
2.受取側のコンポーネントでメッセージチャネルをインポートして、購読(Subscribe)する
3.送信側のコンポーネントでメッセージチャネルをインポートして、送信したいデータを公開(Publish)する
※公開(Publish)を実行すると、購読(Subscribe)したすべてのコンポーネントにデータが送信されます。
下記の例では、Publishコンポーネントで選択した値をLMSで公開(Publish)します。SubscribeコンポーネントはLMSを購読(Subscribe)し、Publishコンポーネントで公開(Publish)された値を画面表示します。
MessageChannel
<?xml version="1.0" encoding="UTF-8"?> <LightningMessageChannel xmlns="http://soap.sforce.com/2006/04/metadata"> <isExposed>true</isExposed> <lightningMessageFields> <fieldName>value</fieldName> </lightningMessageFields> <masterLabel>This is a sample Lightning Message Channel.</masterLabel> </LightningMessageChannel>
sampleMessage
Subscribeコンポーネント
<template> <lightning-card title="Subscriber"> <!-- 親から渡された値を表示する --> <div class="slds-align_absolute-center"> <span>通信値 {value}</span> </div> </lightning-card> </template>
subscriber.html
import { LightningElement, wire, api } from 'lwc'; // LMSで使用するMessageChannelをインポートします。 import { subscribe, unsubscribe, MessageContext, APPLICATION_SCOPE } from 'lightning/messageService'; import SM from '@salesforce/messageChannel/SampleMessage__c'; export default class Subscriber extends LightningElement { @api value; // subscribe()の戻り値を格納する変数です。 subscription; // ワイヤーサービスを使用してMessageContextオブジェクトを作成します。 @wire(MessageContext) messageContext; // subscribe()を実行し、SampleMessageを購読します。 connectedCallback() { this.subscribeToMessageChannel(); } // unsubscribeメソッドで購読状態を解除できます。 disconnectedCallback() { unsubscribe(this.subscription); this.subscription = null; } subscribeToMessageChannel() { this.subscription = subscribe( this.messageContext, SM, // メッセージを受信したときのコールバック関数です。 (message) => { this.value = message.value; }, // 非必須の引数です。APPLICATION_SCOPEにすることで、LWCが非アクティブでもメッセージを受信できます。 { scope: APPLICATION_SCOPE } ); } }
subscriber.js
Publishコンポーネント
<template> <lightning-card title="Publisher"> <div class="slds-grid"> <div class="slds-p-around_medium"> <lightning-combobox name="value" label="value" value={value} options={options} onchange={handleChange} variant="label-hidden"> </lightning-combobox> </div> </div> </lightning-card> </template>
publisher.html
import { LightningElement, wire } from 'lwc'; // LMSで使用するMessageChannelをインポートします。 import { publish, MessageContext } from 'lightning/messageService'; import SMC from '@salesforce/messageChannel/SampleMessage__c'; export default class Publisher extends LightningElement { value = ''; // ワイヤーサービスを使用してMessageContextオブジェクトを作成します。 @wire(MessageContext) messageContext; get options() { return [ { label: '', value: '' }, { label: 'A', value: 'A' }, { label: 'B', value: 'B' }, { label: 'C', value: 'C' } ]; } handleChange(event) { this.value = event.detail.value; this.sendMessage(this.value); } sendMessage(value) { // publishメソッドで選択リストの値をSampleMessageに公開します。 const payload = { type: 'LightningMessageService', value: this.value }; publish(this.messageContext, SMC, payload); } }
publisher.js
最後に
今回は、LWC間の通信方法について紹介しました。
簡単にですが、各通信方法が確認できるサンプルを作成しましたので、みなさんも実装して動きを確認してみてください。
最後までお読みいただき、ありがとうございました。
簡単にですが、各通信方法が確認できるサンプルを作成しましたので、みなさんも実装して動きを確認してみてください。
最後までお読みいただき、ありがとうございました。
46 件