- 原文出自: https://levelup.gitconnected.com/web-components-in-a-nutshell-1e114aa971b9
- 原标题: Web Components in a Nutshell
- 原副标题: 原生浏览器Web Component基础和如何创建
- 翻译文章同步发表在团队的语雀上
说明: 以下使用Web组件来表示Web Component
正文:
在web开发中,代码复用已成为一个聚焦重点。作为一名开发者,我们可能会遇到这样的场景,在多个地方使用一个代码片段来表示自定义的UI。如果我们不是很小心的写出,这可能会让整个代码结构变得不可管理。Web组件提供了一个原生的API来构建可复用的UI块。
什么是Web组件?
Web组件是一系列用来帮助我们创建可复用、具备封装的自定义HTML UI元素的浏览器底层的API。Web组件被认为更加好,是因为他们可以用任意的库或者框架创建,而且你可以立马使用原生JavaScript开始创建你自己的Web组件。
使用Web组件的一大优势在于他们已经在除了微软Edge外其他浏览器中可用,但是我们并不需要担心,因为已经有Polyfills可以解决这个问题。
Web组件由3个主要的技术组成,他们是主要支柱并作为API来构建Web组件。
- 自定义元素(Custom Elements)
- 模板(Templates)
- 影子DOM(Shadow DOM)
让我们来进一步了解这些技术。
1. 自定义元素(Custom Elements)
这些是JavaScript API的集合,可以帮助你创建自己的HTML元素,并且控制你的DOM和行为。我们可以构建他们的层级和指示他们对行为变化做出的响应。例如,你可以创建一个元素像这样<my-element></my-element>
。
2. 模板(Templates)
模板是用户定义的模板在页面加载时并不渲染。之后可以通过创建一个组件实例来多次复用。
3. 影子DOM(Shadow DOM)
影子DOM是JavaScript API组合用以连接封装的DOM。这将会从主文档对象模型中独立渲染,并且他们的行为特性将会保持私有,因此代码片段就不会和代码结构中的其他部分冲突。使用影子DOM后CSS和JavaScript就会像<iframe>
一样分离。
生命周期回调
生命周期回调是定义在自定义元素类定义中的函数。他们有自己唯一的定义目的。他们用于操作我们自定义元素的行为。
connectedCallback
: 这个特殊的函数会在我们的自定义元素初始连接到DOM时进行调用。adoptedCallback
: 这个函数会在我们的自定义函数移动到一个新的文档时调用。attributeChangedCallback
: 如果在我们的自定义元素中有属性变化,例如属性的变更、增加或者删掉,这个特殊的函数会被调用。disconnectedCallback
: 这个特殊的函数当我们的自定义元素从DOM中断开时调用。
现在让我们来看看如何使用原生JavaScript来创建一个Web组件。通过做完这个教程,你可以了解Web组件。
实战
我们要构建什么?
我们要构建一个显示一张当前热门图片的Web组件。我们会使用Giphy API来获取gif,你的代码结构在实现完成后会是如下:
1 | --index.html |
构建教程
首先,我们要创建一个类来包含我们想创建的Web组件的行为。创建一个card.js
的文件,并创建一个如下的类。
1 | class CardComponent extends HTMLElement { |
在类的构造函数中,你需要通过Element.attachShadow()
方法将影子DOM的影子根(shadow root)添加到文档的当前HTML元素中。接着使用<template>
标签在index.html
文件中创建HTML模板。这个模板如下:
1 | <template id="card-view"> |
在添加模板到我们的index.html
文件中后,我们可以使用DOM方法来克隆上面的模板并添加到我们的影子DOM。这需要在构造函数中完成。
1 | class CardComponent extends HTMLElement { |
就像我之前提到的,我们应该再写一个函数来从Giphy API中获取gif。从API中我们将获取到当前热门的图片,以及这个图片上传者提供的标题。在我们开始写这个函数前,先创建一个单独的文件services.js
用以放置URL和API key。创建文件并放置以下代码和你申请的API key。
1 | const API_KEY = '*YOUR_API_KEY*'; |
创建services.js
文件后,添加以下的代码到你的card.js
文件顶部,这样你就可以使用URL来获取gif图片了。
1 | import { url } from './services.js'; |
你可以从这个链接获取你自己的API key: https://developers.giphy.com/
跳回到card.js
文件,并添加以下函数:
1 | render(shadowElem, data){ |
让我来解释一下这些函数。
fetchFromGiphy()
: 这个函数使用async/await获取热门的gif和这个gif的标题,并作为对象进行返回。
render()
: 这个函数用于注入值到影子DOM的元素中。
接着,让这些函数在生命周期回调中被调用。实际上,我们需要当我们的自定义元素连接到DOM时调用这两个函数。我们有connectedCallback()
函数来实现。
1 | async connectedCallback() { |
最后,使用customElements.define()
函数来定义我们的自定义元素。当定义一个自定义元素时,有一些基本原则需要记在心里。define()
函数的第一个参数应该是代码自定义元素名称的字符串。他们不能是一个单独的单词,而是由-
字符在中间。第二个参数我们的定义元素行为的类对象。
1 | customElements.define(‘card-component’, CardComponent); |
现在你已经定义了你的组件,添加card.js
文件到你的index.html
文件中。你可以在HTML文档的任意地方使用<card-component>
元素。最后的index.html
如下:
1 |
|
为了运行,你需要一个服务器。从命令行中全局安装static-server
:
1 | npm install -g static-server |
从你的Web组件项目目录下运行static-server
命令:
1 | static-server |
好了,恭喜!你现在已经拥有你自己的组件。
结论
这篇文章总结了Web组件的基础。这是Web组件的理论和实现。Web组件在帮助代码复用上很有用。你可以从这个项目中检出所有代码。