Web Components基本概念及实例教程

CSS/设计
413
0
0
2022-04-04

Web Components基本概念及实例教程

谷歌公司由于掌握了 Chrome 浏览器,一直在推动浏览器的原生组件,即 Web Components API。相比第三方框架,原生组件简单直接,符合直觉,不用加载任何外部模块,代码量小。目前,它还在不断发展,但已经可用于生产环境。

基本概念

Web Components 由这四种技术组成

  • 自定义元素 (Custom Elements)
  • HTML模板 (HTML Templates)
  • 影子DOM (Shadow DOM)
  • HTML导入 (HTML Imports)

对应的接口

1、四种新的HTML元素: <template>, <content>, <element>, <shadow>

2、与新元素相关的API接口:

  • HTMLTemplateElement
  • HTMLContentElement
  • HTMLElementElement
  • HTMLShadowElement

3、HTMLLinkElement 接口的拓展,以及 <link> 元素

4、一个注册新元素的接口:

  • Document.registerElement()
  • Document.createElement()
  • Document.createElementNS()

5、自定义元素的原型(prototype)可以添加新的生命周期回调(lifecycle callbacks)

6、元素的默认样式中添加新的CSS伪类(pseudo-classes)

  1. :unresolved.

7、影子DOM:

Shadow DOM 为Web组件中的 DOM和 CSS提供了封装。Shadow DOM 使得这些东西与主文档的DOM保持分离。你也可以在一个Web组件外部使用 Shadow DOM本身。

为什么要把一些代码和网页上其他的代码分离?原因之一是,大型站点若CSS没有良好的组织,导航的样式可能就『泄露』到本不应该去的地方,如主要内容区域,反之亦然。随着站点、应用的拓展,这样的事难以避免。

  • ShadowRoot
  • Element.createShadowRoot()
  • Element.getDestinationInsertionPoints()
  • Element.shadowRoot

8、Event 接口的拓展:Event.path

9、Document 接口的拓展

10、Web Components 的样式:

  • 新的伪类: :host、:host()、:host-context()
  • 新的伪元素:::shadow 和 ::content
  • 新的组合器(combinator):/deep/

自定义元素 (Custom Elements)

创建自己的自定义HTML元素,可以有自己的脚本行为和CSS样式。
自定义元素的一个优势是它们的生命周期反应,这允许将行为附加到新元素的“生命周期”的不同部分。

启用自定义元素关键在于 Document.registerElement() 方法,此方法向浏览器注册一个新元素,该元素默认使用 HTMLElement 接口(如果您创建了类似<mytag>的标签,但不注册,它将会使用 HTMLUnknownElement接口。您也可以在例如 <button> 这样的原生元素的基础上创建自定义元素,不过如此一来就不能使用自定义标签名,比如 <my-button> ,而要使用 <button is="my-button"> 这样的语法了)。

生命周期回调(Lifecycle callbacks)

自定义元素可以使用以下生命周期回调函数:

  • createdCallback - 注册元素时执行
  • attachedCallback - 元素插入DOM时执行
  • detachedCallback - 元素被移除DOM时执行
  • attributeChangedCallback - 元素的属性被增、删、改时执行

实例教程

上面介绍了Web Components的一些基本概念,接下来配合这些基本概念,我们将配备一些实例。

下图是一个用户卡片。

Web Components基本概念及实例教程

本文演示如何把这个卡片,写成 Web Components 组件。网页只要插入下面的代码,就会显示用户卡片。

<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>目前还是空的,下面在类里面给出这个元素的内容。

Web Components基本概念及实例教程

上面代码最后一行,this.append()的this表示自定义元素实例。

完成这一步以后,自定义元素内部的 DOM 结构就已经生成了。

template标签

使用 JavaScript 写上一节的 DOM 结构很麻烦,Web Components API 提供了<template>标签,类似vue书写组件的方式,可以在它里面使用 HTML 定义 DOM。

Web Components基本概念及实例教程

然后,改写一下自定义元素的类,为自定义元素加载<template>

Web Components基本概念及实例教程

上面代码中,获取<template>节点以后,克隆了它的所有子元素,这是因为可能有多个自定义元素的实例,这个模板还要留给其他实例使用,所以不能直接移动它的子元素。

到这一步为止,完整的代码如下

Web Components基本概念及实例教程

添加样式

自定义元素还没有样式,可以给它指定全局样式,比如下面这样。

user-card {
 /* ... */ 
}

但是,组件的样式应该与代码封装在一起,只对自定义元素生效,不影响外部的全局样式。所以,可以把样式写在<template>里面,类似scss里面使用scoped的标签。

Web Components基本概念及实例教程

注意:上面代码中,<template>样式里面的:host伪类,指代自定义元素本身。

自定义元素的参数

<user-card>内容现在是在<template>里面设定的,为了组件复用,我们希望把它改成传递参数的形式

Web Components基本概念及实例教程

那么<template>代码也相应改造

Web Components基本概念及实例教程

最后,改一下类的代码,把参数加到自定义元素里面

Web Components基本概念及实例教程

Shadow DOM

我们不希望用户能够看到<user-card>的内部代码,Web Component 允许内部代码隐藏起来,这叫做 Shadow DOM,即这部分 DOM 默认与外部 DOM 隔离,内部任何代码都无法影响外部。

自定义元素的this.attachShadow()方法开启 Shadow DOM,详见下面的代码。

Web Components基本概念及实例教程

上面代码中,this.attachShadow()方法的参数{ mode: 'closed' },表示 Shadow DOM 是封闭的,不允许外部访问。

至此,这个 Web Component 组件就完成了,完整代码可以访问这里。可以看到,整个过程还是很简单的,不像第三方框架那样有复杂的 API。

组件的扩展

在前面的基础上,可以对组件进行扩展。

(1)与用户互动

用户卡片是一个静态组件,如果要与用户互动,也很简单,就是在类里面监听各种事件。

this.$button = shadow.querySelector('button');
this.$button.addEventListener('click', () => {
 // do something
});

(2)组件的封装

上面的例子中,<template>与网页代码放在一起,其实可以用脚本把<template>注入网页。这样的话,JavaScript 脚本跟<template>就能封装成一个 JS 文件,成为独立的组件文件。网页只要加载这个脚本,就能使用<user-card>组件

你以为这个只是才出来的吗,不,已经有完整的组件库啦

Web Components基本概念及实例教程

Web Components基本概念及实例教程

  • 完整的使用指南,号称跨框架。无论是react、vue还是原生项目均可使用。

Web Components基本概念及实例教程

配上地址:

https://xy-ui.codelabo.cn/docs/#/README

https://github.com/XboxYan/xy-ui

链接地址:

http://www.ruanyifeng.com/blog/2019/08/web_components.html

https://www.imooc.com/article/17277

https://xy-ui.codelabo.cn/docs