カスタム要素にデータを渡す (ベータ)

カスタム要素は、サードパーティ Web コンポーネントの構成要素です。カスタム要素にデータを渡すには、属性、プロパティ、または lwc:spread ディレクティブを使用します。データを渡すと、LWC ではデフォルトでデータが属性として設定されます。プロパティは存在する場合にのみ設定されます。

this.attachShadow({ mode: 'closed' }) を使用してシャドウコンテンツを初期化するコンストラクタは、一度だけ呼び出されます。属性やプロパティを使用する場合には、次のガイドラインに留意してください。

属性を使用したデータの受け渡し 

サードパーティ Web コンポーネントが表示された後は、属性の変更が無視されます。属性を監視し、サードパーティ Web コンポーネントに確実に変更を表示するには、observedAttributes() 静的 getter 関数と attributeChangedCallback() メソッドを使用します。attributeChangedCallback() コールバックは、監視している属性が変更されたときに実行されます。属性データのシリアライズとデシリアライズを処理するには、次の例のように getter および setter を使用します。

1class extends HTMLElement {
2    static observedAttributes = ["myAttr"];
3    attributeChangedCallback(attr, oldVal, newVal) {
4      if (attrName === "myAttr") {
5        this.shadow.getElementById("myElement").myAttr = newVal === "true";
6      }
7    }
8    set myAttr(bool) {
9      this.setAttribute("myAttr", bool.toString());
10    }
11    get myAttr() {
12      return this.getAttribute("myAttr") === "true";
13    }
14}

属性の変更によってボタンのカウントを増分する例については、こちらを参照してください。

プロパティを使用したデータの受け渡し 

プロパティを利用する場合は、getter および setter を使用します。

1class extends HTMLElement {
2  _message = 'Hello';
3  set message(value) {
4    this._message = value;
5  }
6  get message() {
7    return this._message;
8  }
9}

たとえば、lwc:spread ディレクティブを使用してプロパティに渡されるカスタム要素があるとします。

1<!-- myMessage.html -->
2<template>
3  <c-message lwc:external lwc:spread={props}></c-message>
4</template>

このカスタム要素はボタンを表示します。ボタンにイベントリスナーを追加するには、addEventListener() を使用します。

1// myMessage.js
2import { LightningElement } from "lwc";
3
4customElements.define(
5  "c-message",
6  class extends HTMLElement {
7    constructor() {
8      super();
9      this.shadow = this.attachShadow({ mode: "closed" });
10      this.shadow.innerHTML = `<button>click</button>`;
11      this.shadow.querySelector("button").addEventListener("click", (event) => {
12        console.log(`message: ${this.message}`);
13      });
14    }
15
16    set message(value) {
17      this._message = value;
18    }
19    get message() {
20      return this._message;
21    }
22  },
23);
24
25export default class MyMessage extends LightningElement {
26  props = {
27    message: "Hello custom element",
28  };
29}

子コンポーネントにデータを渡す 

親コンポーネントに、カスタム要素を定義した子コンポーネントが含まれているとします。lwc:spread ディレクティブを使用して、子コンポーネントにプロパティを渡します。

1<!-- myApp.html -->
2<template>
3  <c-cmp lwc:spread="{myProps}"></c-cmp>
4</template>

キーと値のペアを持つオブジェクトを使用します。

1// myApp.js
2import { LightningElement } from "lwc";
3
4export default class MyApp extends LightningElement {
5  myProps = {
6    name: "Guest",
7    greeting: "Hello",
8  };
9}

子コンポーネントで、カスタム要素のインスタンスを作成します。

1<!-- myCmp.html -->
2<template>
3  <c-custom-el lwc:external> {greeting}, {name} </c-custom-el>
4</template>

JavaScript で constructor() をコールして、プロパティを親コンポーネントに公開します。

1// myCmp.js
2import { LightningElement, api } from "lwc";
3
4customElements.define(
5  "c-custom-el",
6  class extends HTMLElement {
7    constructor() {
8      super();
9      this.attachShadow({ mode: "closed" }).innerHTML = "<slot></slot>";
10    }
11  },
12);
13export default class MyCmp extends LightningElement {
14  @api name;
15  @api greeting;
16}

カスタム要素は次のように表示されます。

1<my-app>
2  #shadow-root (open)
3  |  <my-cmp> 
4  |    #shadow-root (open) 
5  |    |  <c-custom-el>
6  |    |    #shadow-root (closed)
7  |    |    | Hello, Guest
8  |    |  </c-custom-el>
9  |  </my-cmp>
10</my-app>

カスタム要素のスロットにマークアップを渡す 

サードパーティ Web コンポーネントのスロットにマークアップを渡す操作は、LWC コンポーネントのスロットの場合と似ています。

合成 Shadow のスロット実装は、サードパーティ Web コンポーネントではサポートされていません。

Note

サードパーティ Web コンポーネントにいくつかのマークアップがあるとします。

1customElements.define(
2  "c-custom-slot",
3  class extends HTMLElement {
4    constructor() {
5      super();
6      this.attachShadow({ mode: "closed" }).innerHTML = `
7    <h1>My title</h1>
8    <div>
9        <p>Some content here</p>
10    </div>
11    <slot></slot>
12    `;
13    }
14  },
15);

次のスロット化されたコンテンツが <slot> 要素に表示されます。

1<template>
2  <c-custom-slot lwc:external>
3    <div class="slotted">slot content</div>
4  </c-custom-slot>
5</template>

コンポーネントは DOM で次のように表示されます。

1<c-custom-slot>
2  #shadow-root (closed)
3  |  <h1>My title</h1>
4  |  <div><p>Some content here</p></div>
5  |  <slot>
6  |    <div class="slotted">slot content</div>
7  |  </slot>
8</c-custom-slot>

同様に、名前付きスロットを次のように使用することができます。

1// mySlot.js
2import { LightningElement, api } from "lwc";
3
4customElements.define(
5  "c-slotting",
6  class extends HTMLElement {
7    constructor() {
8      super();
9      this.shadow = this.attachShadow({ mode: "closed" });
10      this.shadow.innerHTML = `<slot name="myslot"></slot>`;
11    }
12  },
13);
14export default class MySlot extends LightningElement {}

マークアップに名前付きスロットを含めます。

1<!-- mySlot.html -->
2<c-slotting lwc:external>
3  <p>slotted incorrectly</p>
4  <p slot="myslot">slotted correctly</p>
5</c-slotting>

コンポーネントは DOM で次のように表示されます。

1<my-slot>
2  #shadow-root (open)
3  |  <c-slotting>
4  |    #shadow-root (closed)
5  |    |  <p>slotted incorrectly</p>
6  |    |  <p slot="myslot">slotted correctly</p>
7  |  </c-slotting>
8</my-slot>

サードパーティ Web コンポーネントでのイベントの使用 

サードパーティ Web コンポーネントのイベントは、LWC のイベントと同じように動作します。イベントのバインドは、小文字のイベントについてのみサポートされます。小文字以外を使った名前のイベントを使用するには、addEventListener() API を使用するイベントリスナーを追加します。

constructor() にイベントリスナーを追加します。

1customElements.define(
2  "c-element-with-events",
3  class extends HTMLElement {
4    constructor() {
5      super();
6      this.attachShadow({ mode: "closed" });
7      this.shadow.innerHTML = `CLICK ME!`;
8      this.addEventListener("click", this.handleClick);
9    }
10    handleClick() {
11      this.dispatchEvent(new CustomEvent("lowercaseevent"));
12      this.dispatchEvent(new CustomEvent("camelEvent"));
13    }
14  },
15);

サードパーティ Web コンポーネントの考慮事項 

登録されていないカスタム要素は、ネイティブの HTMLUnknownElement インターフェースのインスタンスとして表示されます。このインターフェースは、HTMLElement を拡張したのもですが、プロパティやメソッドは追加されていません。ブラウザでは、外部コンポーネントが spandiv と同様のネイティブコンポーネントとして処理されます。

登録済みのコンポーネントの場合、エンジンが関連するサードパーティ Web コンポーネントを表示し、ブラウザでのアップグレードを遅延させます。

詳細は、HTML 仕様の「Upgrading elements after their creation (要素を作成した後のアップグレード)」を参照してください。

さらに、サードパーティ Web コンポーネントに関するアップグレードの動作についても考慮してください。

  • サードパーティ Web コンポーネントがアップグレードされない場合、LWC でマウント時と更新時にその属性が設定されます。
  • 遅延アップグレードがある場合は、プロパティの代わりに属性が設定されます。
  • アップグレード後、プロパティが存在する場合は、属性の代わりにプロパティが設定されます。

関連トピック 

The Japanese Summer '24 guide is now live

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