Web Components 入門

組件是前端的發展方向,現在流行的 React 和 Vue 都是組件框架。

谷歌公司由於掌握了 Chrome 瀏覽器,一直在推動瀏覽器的原生組件,即 Web Components API。相比第三方框架,原生組件簡單直接,符合直覺,不用加載任何外部模塊,代碼量小。目前,它還在不斷髮展,但已經可用於生產環境。

Web Components API 內容很多,本文不是全面的教程,只是一個簡單演示,讓大家看一下怎麼用它開發組件。

一、自定義元素

<user-card></user-card>

這種自定義的 HTML 標籤,稱爲自定義元素(custom element)。根據規範,自定義元素的名稱必須包含連詞線,用於區別原生的 HTML 元素。所以,<user-card> 不能寫成<usercard>

二、customElements.define()

自定義元素需要使用 JavaScript 定義一個類,所有 <user-card> 都會是這個類的實例。

class UserCard extends HTMLElement {
  constructor() {
    super();
  }
}

上面代碼中,UserCard 就是自定義元素的類。注意,這個類的父類是 HTMLElement,因此繼承了 HTML 元素的特性。

接着,使用瀏覽器原生的 customElements.define() 方法,告訴瀏覽器 <user-card> 元素與這個類關聯。

window.customElements.define('user-card', UserCard);

三、自定義元素的內容

自定義元素 <user-card> 目前還是空的,下面在類裏面給出這個元素的內容。

class UserCard extends HTMLElement {
  constructor() {
    super();
    var image = document.createElement('img');
    image.src = 'https://semantic-ui.com/images/avatar2/large/kristy.png';
    image.classList.add('image');
    var container = document.createElement('div');
    container.classList.add('container');
    var name = document.createElement('p');
    name.classList.add('name');
    name.innerText = 'User Name';
    var email = document.createElement('p');
    email.classList.add('email');
    email.innerText = 'yourmail@some-email.com';
    var button = document.createElement('button');
    button.classList.add('button');
    button.innerText = 'Follow';
    container.append(name, email, button);
    this.append(image, container);
  }
}

上面代碼最後一行,this.append() 的 this 表示自定義元素實例。

完成這一步以後,自定義元素內部的 DOM 結構就已經生成了。

四、<template> 標籤

使用 JavaScript 寫上一節的 DOM 結構很麻煩,Web Components API 提供了 <template> 標籤,可以在它裏面使用 HTML 定義 DOM。

<template>
  <img src="https://semantic-ui.com/images/avatar2/large/kristy.png">
  <div>
    <p>User Name</p>
    <p>yourmail@some-email.com</p>
    <button>Follow</button>
  </div>
</template>

然後,改寫一下自定義元素的類,爲自定義元素加載 <template>

class UserCard extends HTMLElement {
  constructor() {
    super();
    var templateElem = document.getElementById('userCardTemplate');
    var content = templateElem.content.cloneNode(true);
    this.appendChild(content);
  }
}

上面代碼中,獲取 <template> 節點以後,克隆了它的所有子元素,這是因爲可能有多個自定義元素的實例,這個模板還要留給其他實例使用,所以不能直接移動它的子元素。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/iFTgBmc4VBFWG35bn5mabg