スロットにマークアップを渡す

親コンポーネントがコンポーネントにマークアップを渡すことができるようにコンポーネントの HTML ファイルにスロットを追加します。コンポーネントは 0 個以上のスロットを持つことができます。

スロット (<slot></slot>) は、親コンポーネントがコンポーネントの本体に渡すマークアップのプレースホルダです。

スロットに Aura コンポーネントを渡すことはできません。Lightning Web コンポーネントを Aura コンポーネント内にネストした場合も、スロットに渡すことはできません。

Important

名前なしスロット 

この例には、名前なしスロットがあります。名前なしスロットは、親コンポーネントが c-slot-demo の本体に渡すマークアップのプレースホルダとして <slot> 要素を使用します。

1<!-- slotDemo.html -->
2<template>
3  <h1>Add content to slot</h1>
4  <div>
5    <slot></slot>
6  </div>
7</template>

c-slot-demo を使用する親コンポーネントのマークアップを次に示します。

1<!-- slotWrapper.html -->
2<template>
3  <c-slot-demo>
4    <p>content from parent</p>
5  </c-slot-demo>
6</template>

c-slot-demo が表示されるとき、名前なしスロットは、c-slot-demo の本体に渡されるマークアップに置き換えられます。表示される c-slot-wrapper の出力を次に示します。

1<h1>Add content to slot</h1>
2<div>
3  <slot>
4    <p>content from parent</p>
5  </slot>
6</div>

コンポーネントに名前なしスロットが複数ある場合、その本体に渡されたマークアップは、すべての名前なしスロットに挿入されます。ただし、コンポーネントの名前なしスロットの数は、通常は 0 個または 1 個です。

名前付きスロット 

次の例のコンポーネントには、2 つの名前付きスロットと 1 つの名前なしスロットがあります。

1<!-- namedSlots.html -->
2<template>
3  <p>First Name: <slot name="firstName">Default first name</slot></p>
4  <p>Last Name: <slot name="lastName">Default last name</slot></p>
5  <p>Description: <slot>Default description</slot></p>
6</template>

HTML 要素の slot 属性には動的値を設定できます。以下では、<span> 要素の slot 属性が変数 dynamicName に設定されています。

1<template>
2  <c-item>
3    <span slot={dynamicName}></span>
4  </c-item>
5</template>

slot 属性に渡される動的値は、文字列に設定されます。たとえば、この属性に数値の 4 を渡すと、文字列の "4" に変換されます。文字列に変換できない Symbol() などのデータ型を渡した場合は、TypeError がスローされます。

この変更は、<slot> 要素の属性には影響しません。たとえば、<slot> 要素の name 属性には、引き続き静的文字列を渡す必要があります。

1<template>
2  <slot name="”staticName”"> </slot>
3</template>

c-named-slots を使用する親コンポーネントのマークアップを次に示します。

1<!-- slotsWrapper.html -->
2<template>
3  <c-named-slots>
4    <span slot="firstName">Willy</span>
5    <span slot="lastName">Wonka</span>
6    <span>Chocolatier</span>
7  </c-named-slots>
8</template>

c-slots-wrapper コンポーネントは、次のような受け渡しを行います。

  • WillyfirstName スロットに渡します。
  • WonkalastName スロットに渡します。
  • Chocolatier を名前なしスロットに渡します。

表示される出力を次に示します。

1<c-named-slots>
2  <p>
3    First Name:
4    <slot name="firstName"><span slot="firstName">Willy</span></slot>
5  </p>
6  <p>
7    Last Name:
8    <slot name="lastName"><span slot="lastName">Wonka</span></slot>
9  </p>
10  <p>
11    Description:
12    <slot><span>Chocolatier</span></slot>
13  </p>
14</c-named-slots>

スロット経由で渡される要素へのアクセス 

<slot></slot> 要素は、コンポーネントのシャドウツリーの一部です。そのシャドウツリーの要素にアクセスするには、コンポーネントで this.template.querySelector()this.template.querySelectorAll() をコールします。

ただし、スロットに渡される DOM 要素は、コンポーネントのシャドウツリーの一部ではありません。スロット経由で渡される要素にアクセスするには、コンポーネントで this.querySelector()this.querySelectorAll() をコールします。

次の例は、DOM 要素を子のコンテキストの子コンポーネントに渡す方法を示しています。this.querySelector()this.querySelectorAll() のセレクタ名 (要素など) を指定します。

1// namedSlots.js
2import { LightningElement } from "lwc";
3
4export default class NamedSlots extends LightningElement {
5  renderedCallback() {
6    this.querySelector("span"); // <span>push the green button.</span>
7    this.querySelectorAll("span"); // [<span>push the green button</span>, <span>push the red button</span>]
8  }
9}

この例の場合、querySelector は、要素 span を受け入れます。

idquerySelector などのクエリメソッドに渡さないでください。HTML テンプレートが表示されるときに、id 値がグローバルに一意な値に変換される場合があります。JavaScript の id セレクタを使用する場合、その ID は、変換された id に一致しません。

Note

条件に応じたスロットの表示 

スロットを条件に応じてレンダリングするには、lwc:iflwc:elselwc:elseif などのディレクティブを使用してスロットを <template> タグ内にネストします。

1<template>
2  <template lwc:if={expression}>
3    <div class="my-class">
4      <slot></slot>
5    </div>
6  </template>
7  <template lwc:else>
8    <slot></slot>
9  </template>
10</template>

テンプレートコンパイラは、条件ディレクティブのそれぞれを有効な使用事例の 1 つとして処理し、<slot> を 2 回表示しないものと認識します。

従来の if:true および if:false ディレクティブを使用した場合は、<slot> を一度だけ表示するかどうかが不明なため、コンパイラが重複スロットについて警告します。たとえば、expression getter は毎回異なる戻り値を持つことができます。

slotchange でのコードの実行 

すべての <slot> 要素では、slotchange イベントがサポートされます。<slot> 要素内のノードの直接の子が変更されると、slotchange イベントが起動されます。たとえば、これは新しいコンテンツが追加または削除されたときに発生します。このイベントがサポートされるのは、<slot> 要素のみです。

<slot> 要素の子の内部の変更では、slotchange イベントはトリガされません。

次の例では、<slot> 要素が slotchange イベントを処理します。

1<!-- container.html -->
2<template>
3  <slot onslotchange={handleSlotChange}></slot>
4</template>
1// container.js
2handleSlotChange (e) {
3   console.log("New slotted content has been added or removed!");
4}

コンポーネント c-child は、スロットに渡されます。

1<c-container>
2  <c-child></c-child>
3  <template lwc:if={addOneMore}>
4    <c-child></c-child>
5  </template>
6</c-container>

フラグ addOneMore が True に設定されている場合、コンポーネントが初めて表示されるときにコンソールに出力が表示されます。

1<!-- child.html -->
2<template>
3  <button onclick={handleClick}>Toggle Footer</button>
4  <template lwc:if={showFooter}>
5    <footer>Footer content</footer>
6  </template>
7</template>

showFooter が true で、フッター要素が追加された場合でも、slotchange イベントはトリガされません。

関連トピック

The Japanese Summer '24 guide is now live

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