Web Components 入门
组件是前端的发展方向,现在流行的 React 和 Vue 都是组件框架。
谷歌公司由于掌握了 Chrome 浏览器,一直在推动浏览器的原生组件,即 Web Components API。相比第三方框架,原生组件简单直接,符合直觉,不用加载任何外部模块,代码量小。目前,它还在不断发展,但已经可用于生产环境。
Web Components API 内容很多,本文不是全面的教程,只是一个简单演示,让大家看一下怎么用它开发组件。
一、自定义元素
这种自定义的 HTML 标签,称为自定义元素(custom element)。根据规范,自定义元素的名称必须包含连词线,用于区别原生的 HTML 元素。所以,
不能写成
。
二、customElements.define()
自定义元素需要使用 JavaScript 定义一个类,所有
都会是这个类的实例。
class UserCard extends HTMLElement {
constructor() {
super();
}
}
上面代码中,UserCard
就是自定义元素的类。注意,这个类的父类是 HTMLElement,因此继承了 HTML 元素的特性。
接着,使用浏览器原生的 customElements.define()
方法,告诉浏览器
元素与这个类关联。
window.customElements.define('user-card', UserCard);
三、自定义元素的内容
自定义元素
目前还是空的,下面在类里面给出这个元素的内容。
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 结构就已经生成了。
四、 标签
使用 JavaScript 写上一节的 DOM 结构很麻烦,Web Components API 提供了 标签,可以在它里面使用 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">yourmail@some-email.comp>
<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);
}
}
上面代码中,获取 节点以后,克隆了它的所有子元素,这是因为可能有多个自定义元素的实例,这个模板还要留给其他实例使用,所以不能直接移动它的子元素。