🔰implementing components

browserweb components ⟩ implement

1️⃣ 定義繼承自 HTMLElement 的 class

首先,你需要定義一個 JavaScript class,這個類別繼承自 HTMLElement。這個類別將定義你的 Web Component 的行為。

// ⭐️ 1️⃣ 定義一個繼承自 HTMLElement 的 class
class MyComponent extends HTMLElement {
  constructor() {
  
    // ⭐️ 呼叫父類別的 constructor
    super(); 

    // 在這裡初始化你的 component
  }
}

2️⃣ 建立 Shadow DOM

Shadow DOM 允許你為你的 Web Component 創建一個封裝的 DOM 樹。這意味著 component 內部的樣式和腳本不會影響到頁面的其他部分,反之亦然。

constructor() {

  super();

  // ⭐️ 2️⃣ 建立 shadow DOM
  //   mode: 
  //   - 'open'  : 允許 JS 從外部訪問 shadow DOM
  //   - 'closed': 不允許
  this.attachShadow({ mode: 'open' }); 
}

3️⃣ 建立樣板(Template)

你可以使用 <template> 元素來定義你的 Web Component 的 HTML 結構。這樣做的好處是可以避免直接操作 DOM,提高效能。

<!-- ⭐️ 3️⃣ 建立樣板 -->
<template id="my-component-template">

  <style>
    /* component 的樣式 */
    .container {
      border: 1px solid black;
      padding: 10px;
    }
  </style>
  
  <div class="container">
    <h1>Hello from My Component!</h1>
    <p>
      <!-- <slot> 是一個 placeholder,允許使用者在 component 標籤內插入內容 -->
      <slot></slot>
    </p>  
  </div>
  
</template>

4️⃣ 將樣板加入 Shadow DOM

在你的 component 類別中,使用 JavaScript 將樣板的內容複製到 Shadow DOM 中:

constructor() {
  super();
  this.attachShadow({ mode: 'open' });

  // ⭐️ 4️⃣ append template content to shadow root
  const template = document.getElementById('my-component-template');
  this.shadowRoot.appendChild(template.content.cloneNode(true));
}

或者也可以直接將 3️⃣ 4️⃣ 兩個步驟濃縮成這樣:

// in constructor()
// ⭐️ 4️⃣ append template content to shadow root
this.shadowRoot.innerHTML = `
    <style> ... </style>
    <div class="container"> ... </div>
`;

5️⃣ 註冊 Component

使用 customElements.define() 註冊 Web Component:

  • 注意:component 的標籤名稱必須包含一個連字號 "-"

// ⭐️ 5️⃣ 註冊 Component       ╭──tag name──╮  ╭─ class ─╮
window.customElements.define('my-component', MyComponent);

Last updated