スロットとデータを使用したコンポーネントの構成方法の比較

他のコンポーネントを含むコンポーネントを作成する場合、コンポーネントの階層のライフサイクルを考慮して、スロットを使用する宣言型のアプローチや、子コンポーネントが親のデータ変更に反応するデータ駆動型のアプローチを使用します。

コンポーネントを宣言的に作成するための一般的なパターンは次のようになります。

1<c-parent>
2  <c-custom-child></c-custom-child>
3  <c-custom-child></c-custom-child>
4</c-parent>

この例には、slot 要素を使用する c-parent コンポーネントがあります。コンシューマにとっては便利ですが、slot 要素を通過するコンテンツのライフサイクルを管理する必要があります。

スロットに渡されたコンテンツを管理する方法はいくつかあります。

  • slotchange イベントを使用します。これが推奨される方法です。slotchange は DOM を通って上に伝達しますが、シャドウ境界を越えないので、スロットを含む親コンポーネントが反応できます。
  • カスタムイベントを使用して、子コンポーネントの変更を親コンポーネントに通知することで、操作するコンポーネントのメソッドを非公開にすることができます。ネイティブの Shadow を使用するようにコンポーネントを徐々に移行しており、これによりコンポーネントは slotchange イベントを使用するように強制されるため、この方法は推奨されなくなりました。

スロットでの slotchange イベントの使用 

スロットに slotchange イベントを使用することで、親と子コンポーネント間の slot コンテンツのライフサイクルを管理できます。このパターンの例として、子 lightning-button コンポーネントを使用する lightning-button-group 基本コンポーネントが挙げられます。

1<lightning-button-group>
2  <lightning-button label="Refresh"></lightning-button>
3  <lightning-button label="Edit"></lightning-button>
4  <lightning-button label="Save"></lightning-button>
5</lightning-button-group>

親の lightning-button-group コンポーネントには、slot 要素と、渡すコンテンツのライフサイクルを管理する onslotchange イベントが含まれています。

1<!-- buttonGroup.html -->
2<template>
3  <slot onslotchange={handleSlotChange}></slot>
4</template>

基本コンポーネントの例は、デモの目的のためにのみ示しています。基本コンポーネントの内部は変更される場合があります。コンポーネントの機能や動作の変更は文書化されますが、内部の変更は文書化されません。基本コンポーネントの公開属性とメソッドについては、コンポーネントの参照を確認してください。

Note

slotchange ハンドラは、スロットの内容が変更された場合に、スロット化された要素の更新を処理します。この場合、親の lightning-button-group コンポーネントは、グループ内の表示順序 (先頭、中間、末尾) に基づくか、グループ内の唯一のボタンかどうかに基づいて、子の lightning-button コンポーネントの CSS クラスを決定します。

1// buttonGroup.js
2handleSlotChange(event) {
3  const slot = event.target;
4  const children = slot.assignedElements() || [];
5
6  // Loop through each child and
7  // set the order value based on position in the group
8  this.updateGroupOrder(children); }

getter を使用してボタンクラスを変更します。

1<!-- button.html -->
2<template>
3  <button class={computedButtonClass} ...>{label}</button>
4</template>
1// button.js
2get computedButtonClass() {
3    return classSet('slds-button')
4    .add({
5        // Other button classes here
6        'slds-button_first': this._order === 'first',
7        'slds-button_middle': this._order === 'middle',
8        'slds-button_last': this._order === 'last'
9    })
10    .toString();
11}

lightning-button-group コンポーネントが lightning-button コンポーネントを登録できるように、登録イベントを起動します。

1// button.js
2connectedCallback() {
3  this._connected = true;
4    const privatebuttonregister = new CustomEvent('privatebuttonregister', {
5        bubbles: true,
6        detail: {
7            callbacks: {
8                setOrder: this.setOrder.bind(this),
9                setDeRegistrationCallback: (deRegistrationCallback) => {
10                    this._deRegistrationCallback = deRegistrationCallback;
11                }
12            }
13        }
14    });
15
16    this.dispatchEvent(privatebuttonregister);
17}

子コンポーネントが使用できなくなったときに、親コンポーネントに通知します。

1// button.js
2disconnectedCallback() {
3  this._connected = false;
4  if (this._deRegistrationCallback) {
5      this._deRegistrationCallback();
6  }
7}

データ駆動型の方法の使用 

データ駆動型の方法を使用することで、データが変更されたときにコンポーネントがアクティブに変更を取得します。

この例では、データ駆動型の方法を使用して子コンポーネントを構成します。

1<template>
2  <div class="c-parent">
3    <template for:each={itemsData} for:item="itemData">
4      <c-child onclick={onItemSelect} id={itemData.id} key={itemData.id}> </c-child>
5    </template>
6  </div>
7</template>

データを渡すには、JavaScript オブジェクトを使用します。子コンポーネントは、その親からのデータの変更にのみ反応します。

1itemsData = [
2    {
3        label : 'custom label 1',
4        id : 'custom-id-1'
5        selected : false
6    },
7    {
8        label : 'custom label 2',
9        id : 'custom-id-2'
10        selected : false
11    }
12]

使用事例が複雑な場合は、データ駆動型の方法をお勧めします。データ駆動型の方法を使用して作成された基本コンポーネントの例は lightning-datatable です。

関連トピック

The Japanese Summer '24 guide is now live

日本語の Summer '24 ガイドが公開されました! 「Component Reference (コンポーネントリファレンス)」は、以前と同様にコンポーネントライブラリにあります。