カスタム要素の使用 (ベータ)

この機能はベータサービスです。ベータサービスはお客様独自の裁量で試行するものとします。ベータ機能の使用には、「Agreements and Terms」に記載されたベータサービス規約が適用されます。

Note

サードパーティ Web コンポーネントは customElements.define() を使用して作成できる Web コンポーネントであり、LWC アプリケーションで再利用できるカスタム要素になります。サードパーティ Web コンポーネントを使用していない限り、LWC でカスタム要素を使用する必要はありません。この記事の目的では、カスタム要素とサードパーティ Web コンポーネントは同じ意味になります。

Lightning Locker ではサードパーティ Web コンポーネントがサポートされていないため、Salesforce 組織で Lightning Web セキュリティ (LWS) が有効になっている必要があります

Note

カスタム要素では、次の条件に従う必要があります。

  • classconstructor() を使用してカスタム要素を初期化します。
  • Shadow DOM または Light DOM を使用します。Shadow DOM については、LWS で closed モードのみがサポートされています。
  • customElements.define(name, constructor) を使用して、カスタム要素を CustomElementRegistry に登録します。name はハイフンを含み、ページ内で一意である必要があります。

カスタム要素には、<template> タグを任意に使用することができます。<template> タグは document.createElement("template"); を使用して作成することができます。LWC の HTML テンプレートでは、<template> タグをネストすることはできません。

カスタム要素の定義 

LWC では、カスタム要素はサードパーティ Web コンポーネントを使用する場合にのみ必要です。LWC にサードパーティ Web コンポーネントを実装する場合、そのコンポーネントのドキュメントで使用方法を確認することをお勧めします。

サードパーティの Web コンポーネントには、HTMLElement クラスを拡張したカスタム要素定義が含まれています。カスタム要素の定義では、要素の表示方法と、要素が追加または削除されたときの処理を記述します。

1class MyCustomElement extends HTMLElement {
2  constructor() {
3    super();
4    /* custom element created */
5  }
6  connectedCallback() {
7    /* element is added to document */
8  }
9  disconnectedCallback() {
10    /* element is removed from the document */
11  }
12  static get observedAttributes() {
13    return [
14      /* array of attribute names to monitor for changes */
15    ];
16  }
17  attributeChangedCallback(name, oldValue, newValue) {
18    /* one of attributes listed above is modified */
19  }
20  adoptedCallback() {
21    /* element is moved to a new document */
22  }
23}
24/* register the element */
25customElements.define("my-custom-element", MyCustomElement);

サードパーティ Web コンポーネントの動作は、connectedCallback()disconnectedCallback() などのライフサイクルコールバック内に記述されています。

  • constructor() - カスタム要素が初期化されるときにコールされます。super() をコールする必要があり、シャドウの内容を設定するなど、表示前の処理を指定できます。
  • connectedCallback() - カスタム要素が DOM に接続されるときに呼び出されます。
  • disconnectedCallback() - カスタム要素が DOM から切断されたときに呼び出されます。
  • observedAttributes() - 監視する属性の配列を返します。
  • attributeChangedCallback() - 属性が追加、削除、変更されたときに呼び出されます。observeAttributes() で、監視する属性を指定します。
  • adoptedCallback() - カスタム要素が新しいドキュメントに移動されると呼び出されます。

カスタム要素のコンストラクタの作成 

LWC では、カスタム要素はサードパーティ Web コンポーネントを使用する場合にのみ必要です。LWC にサードパーティ Web コンポーネントを実装する場合、そのコンポーネントのドキュメントで使用方法を確認することをお勧めします。

サードパーティ Web コンポーネントには、初期状態とデフォルト値を設定し、イベントリスナーを設定し、さらにシャドウルートを作成するコンストラクタが含まれています。

プロトタイプチェーンを確立するには、コンストラクタで super() をコールします。this.attachShadow() を使用してカスタム要素にシャドウルートを接続します。LWS ではモードを closed に設定する必要があります。「Lightning Web セキュリティと Lightning Locker の比較」を参照してください。

closed モードでは、shadowRoot プロパティは null を返すので、shadowRoot を使用して要素のシャドウルートにアクセスしたり操作したりすることはできません。closed モードでカスタム要素を作成する場合は、シャドウルートへの参照を shadow__shadowRoot などの別の変数で保存します。

Note

要素の内部 Shadow DOM 構造を作成するには、.innerHTML を使用してコンテンツを追加します。この例では、LWC コンポーネントのライフサイクルの外側でカスタム要素を定義しています。

1//myComponent.js
2import { LightningElement } from "lwc";
3
4customElements.define(
5  "my-custom-element",
6  class extends HTMLElement {
7    constructor() {
8      super();
9      this.attachShadow({ mode: "closed" }).innerHTML = "<div>Custom Element Constructor</div>";
10    }
11  },
12);
13
14export default class MyComponent extends LightningElement {
15  greeting = "World";
16}

カスタム要素の属性や子要素を操作するには、代わりに connectedCallback() または renderedCallback() を使用します。たとえば、要素を作成し、その要素に属性を設定する場合は、いずれかのライフサイクルコールバックまで遅延させ、属性が変更されたときに attributeChangedCallback() を使用してコールバックを定義します。詳細は、カスタム要素の仕様を参照してください。

LWC でのカスタム要素の使用 

LWC テンプレートでカスタム要素を使用するには、lwc:external 要素を使用します。

1<!-- myComponent.html -->
2<template>
3  <div class="slds-var-m-around_medium">Hello, {greeting}!</div>
4  <my-custom-element lwc:external></my-custom-element>
5</template>

例: ボタンの表示ラベルをカウントアップするカスタム要素の作成 

次の例は、カスタム要素の構造を示しています。この例では、押されたときに表示ラベルのカウンタを増分するボタンを作成しています。

1//myCounterButton.js
2import { LightningElement } from "lwc";
3
4customElements.define(
5  "my-counter",
6  class extends HTMLElement {
7    count = 0;
8    handler = null;
9    shadow = null;
10    constructor() {
11      super();
12      this.shadow = this.attachShadow({ mode: "closed" });
13      this.shadow.innerHTML = `Button:<button>${this.count}</button>`;
14    }
15    connectedCallback() {
16      this.handler = () => {
17        this.count++;
18        this.shadow.firstElementChild.innerHTML = this.count;
19      };
20      this.shadow.firstElementChild.addEventListener("click", this.handler);
21    }
22    disconnectedCallback() {
23      this.shadow.firstElementChild.removeEventListener("click", this.handler);
24    }
25  },
26);
27
28export default class MyCounterButton extends LightningElement {
29  // your LWC component definition here
30}

LWC でカスタム要素を使用するには、lwc:external ディレクティブを使用してテンプレートに追加します。

1<!-- myCounterButton.html -->
2<template>
3  <my-counter lwc:external></my-counter>
4</template>

コンポーネントは DOM で次のように表示されます。ボタンの表示ラベル ${this.count} はクリックされるたびに増分されます。

1<my-counter-button>
2    <my-counter>
3      #shadow-root (closed)
4      |  "Button:"
5      |  <button>0</button>
6    </my-counter>
7</my-counter-button>

例: 属性変更コールバックによるボタンのカウントアップ 

この例は前の例と似ていますが、カスタム要素の count 属性を監視し、属性が変更されたときに attributeChangedCallback() を使用してコールバックを定義します。

1//myCounterWithCallback.js
2import { LightningElement } from "lwc";
3
4customElements.define(
5  "my-counter",
6  class MyCounter extends HTMLElement {
7    constructor() {
8      super();
9      this.shadow = this.attachShadow({ mode: "closed" });
10    }
11
12    get count() {
13      return this.getAttribute("count");
14    }
15
16    set count(val) {
17      this.setAttribute("count", val);
18    }
19
20    connectedCallback() {
21      this.renderButton();
22      let btn = this.shadow.querySelector("#btn");
23      btn.addEventListener("click", this.increment.bind(this));
24    }
25
26    static get observedAttributes() {
27      return ["count"];
28    }
29
30    attributeChangedCallback(prop, oldVal, newValue) {
31      if (prop === "count") {
32        this.renderButton();
33        let btn = this.shadow.querySelector("#btn");
34        btn.addEventListener("click", this.increment.bind(this));
35        // do something else
36      }
37    }
38
39    increment() {
40      this.count++;
41    }
42
43    renderButton() {
44      this.shadow.innerHTML = `
45        <button id="btn">${this.count}</button>
46      `;
47    }
48  },
49);
50
51export default class extends LightningElement {}

カスタム要素タグを LWC テンプレートに追加します。

1<!-- myCounterWithCallback.html -->
2<template>
3  <my-counter count="0" lwc:external></my-counter>
4</template>

関連トピック 

カスタム要素 - 再利用可能な Web コンポーネント

The Japanese Summer '24 guide is now live

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