前言
组件的概念在Web上已经存在一段时间了,Web Components是一个Web组件标准,通过一种标准化的非侵入的方式封装一个组件,每个组件能组织好它自身的HTML、CSS、JavaScript,并且不会干扰页面上的其他代码Web Components主要由以下几个部分组成HTML templates(HTML模板)slots (slots槽) 和 元素使您可以编写不在呈现页面中显示的标记模板。然后它们可以作为自定义元素结构的基础被多次重用。
templates
templates小例子
上面代码完成了一个基本的templates小例子,虽然是个简单的例子,但已经可以开始了解它的作用了
slots(添加灵活度)
我们使用 让它能在单个实例中通过声明式的语法展示不同的文本
defaultText
如果模板对象添加到 html 脚本中时槽的内容还没定义, 或者浏览器不支持槽,将显示默认的defaultText
Let's have some different text!
同作用
Shadow DOM(影子DOM)
一组JavaScript API,用于将封装的“影子”DOM树附加到元素(与主文档DOM分开呈现)并控制其关联的功能。通过这种方式,您可以保持元素的功能私有,这样它们就可以被脚本化和样式化,而不用担心与文档的其他部分发生冲突。
Shadow DOM案例
我们定义一个 web 组件使用模板作为阴影(shadow) DOM 的内容
Custom elements(自定义元素)
Web Components 标准非常重要的一个特性是,它使开发者能够将HTML页面的功能封装为 custom elements(自定义标签),而往常,开发者不得不写一大堆冗长、深层嵌套的标签来实现同样的页面功能
CustomElementRegistry
接口的实例用来处理 web 文档中的 custom elements — 该对象允许你注册一个 custom element,返回已注册 custom elements 的信息
CustomElementRegistry.define()
方法用来注册一个 custom emelent,该方法接受以下参数:
- 表示所创建的元素名称的符合 DOMString 标准的字符串。注意,custom element 的名称不能是单个单词,且其中必须要有短横线。
- 用于定义元素行为的 类 。
- 可选参数,一个包含 extends 属性的配置对象,是可选参数。它指定了所创建的元素继承自哪个内置元素,可以继承任何内置元素。
HTML Imports
用于将 HTML 代码及 Web Component 导入到网页中。然而,在交叉参考 ES Module 规范后,Firefox 团队认为这不是一种最佳实践,该规范也就没多少人在推动了。就不做过多解析
Component例子
Autonomous custom elements
class PopUpInfo extends HTMLElement {
constructor() {
// 必须首先调用 super方法
super();
// 元素的功能代码
// 创建一个 shadow root
var shadow = this.attachShadow();
// 创建一个 spans
var wrapper = document.createElement('span');
wrapper.setAttribute('class','wrapper');
var icon = document.createElement('span');
icon.setAttribute('class','icon');
icon.setAttribute('tabindex', 0);
var info = document.createElement('span');
info.setAttribute('class','info');
// 获取text属性上的内容,并添加到一个span标签内
var text = this.getAttribute('text');
info.textContent = text;
// 插入 icon
var imgUrl;
if(this.hasAttribute('img')) {
imgUrl = this.getAttribute('img');
} else {
imgUrl = 'img/default.png';
}
var img = document.createElement('img');
img.src = imgUrl;
icon.appendChild(img);
// 创建一些 CSS,并应用到 shadow dom上
var style = document.createElement('style');
style.textContent = '.wrapper {' +
// 简洁起见,省略了具体的CSS
// 将创建的元素附加到 shadow dom
shadow.appendChild(style);
shadow.appendChild(wrapper);
wrapper.appendChild(icon);
wrapper.appendChild(info);
}
}
我们使用之前提到的define()方法将 custom element注册到CustomElementRegistry上,在方法的参数里,我们指定了元素的名称,以及定义了元素功能的类
customElements.define('popup-info', PopUpInfo);
我们就可以使用PopUpInfo
生命周期
在custom element的构造函数中,可以指定多个不同的回调函数,它们将会在元素的不同生命时期被调用:
connectedCallback:当 custom element首次被插入文档DOM时,被调用。
disconnectedCallback:当 custom element从文档DOM中删除时,被调用。
adoptedCallback:当 custom element被移动到新的文档时,被调用。
attributeChangedCallback: 当 custom element增加、删除、修改自身属性时,被调用。
兼容性
Shadow DOM 第二版和 Custom Element 第二版在 Chrome、Safari、三星浏览器上已经支持,还被 Firefox 列为要支持的特性,希望很大。而 Edge 依然在考虑是否支持
总结
Web Components 总的来说是提供一整套完善的封装机制来把 Web 组件化这个东西标准化,这样可以更好推动组件的复用。Custom Elements 提供了自定义元素和标签的能力,template 提供组件模板,而 Shadow DOM 则处理组件间代码隔离的问题。
现代框架比如说 React、Angular、Vue 进一步把组件放在开发的前列,并作为核心要素用在它们自己的框架结构上,而原生的Web Components是希望能打破这些框架间的界限。让开发者不用再去理解那么多抽象概念,释放更多的潜力。
领取专属 10元无门槛券
私享最新 技术干货