Web Components 入門

組件是前端的發(fā)展方向,現(xiàn)在流行的 React 和 Vue 都是組件框架。
谷歌公司由于掌握了 Chrome 瀏覽器,一直在推動瀏覽器的原生組件,即 Web Components API。相比第三方框架,原生組件簡單直接,符合直覺,不用加載任何外部模塊,代碼量小。目前,它還在不斷發(fā)展,但已經(jīng)可用于生產(chǎn)環(huán)境。
Web Components API 內(nèi)容很多,本文不是全面的教程,只是一個簡單演示,讓大家看一下怎么用它開發(fā)組件。
一、自定義元素
這種自定義的 HTML 標(biāo)簽,稱為自定義元素(custom element)。根據(jù)規(guī)范,自定義元素的名稱必須包含連詞線,用于區(qū)別原生的 HTML 元素。所以,?不能寫成。
二、customElements.define()
自定義元素需要使用 JavaScript 定義一個類,所有??都會是這個類的實例。
class UserCard extends HTMLElement {constructor() {super();}}
上面代碼中,UserCard?就是自定義元素的類。注意,這個類的父類是 HTMLElement,因此繼承了 HTML 元素的特性。
接著,使用瀏覽器原生的?customElements.define()?方法,告訴瀏覽器??元素與這個類關(guān)聯(lián)。
window.customElements.define('user-card', UserCard);三、自定義元素的內(nèi)容
自定義元素??目前還是空的,下面在類里面給出這個元素的內(nèi)容。
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 = '[email protected]';var button = document.createElement('button');button.classList.add('button');button.innerText = 'Follow';container.append(name, email, button);this.append(image, container);}}
上面代碼最后一行,this.append()?的?this?表示自定義元素實例。
完成這一步以后,自定義元素內(nèi)部的 DOM 結(jié)構(gòu)就已經(jīng)生成了。
四、?標(biāo)簽
使用 JavaScript 寫上一節(jié)的 DOM 結(jié)構(gòu)很麻煩,Web Components API 提供了??標(biāo)簽,可以在它里面使用 HTML 定義 DOM。
<template id="userCardTemplate"><img src="https://semantic-ui.com/images/avatar2/large/kristy.png" class="image"><div class="container"><p class="name">User Namep><p class="email">[email protected]p><button class="button">Followbutton>div>template>
然后,改寫一下自定義元素的類,為自定義元素加載?。
class UserCard extends HTMLElement {constructor() {super();var templateElem = document.getElementById('userCardTemplate');var content = templateElem.content.cloneNode(true);this.appendChild(content);}}
上面代碼中,獲取??節(jié)點以后,克隆了它的所有子元素,這是因為可能有多個自定義元素的實例,這個模板還要留給其他實例使用,所以不能直接移動它的子元素。
