前言
由于最近作者在学习微前端,web component也是其中一大特性,部分微前端框架使用到,也是深入学习了一下相关的知识,分享出来。
Web Component是什么?
Web Component 实际上一系列技术的组合,主要包含 3 部分:
- 自定义元素。 在 HTML 基础标签外扩展自定义标签元素,也就是我们平时使用框架的"组件";
- Shadow DOM。 主要用于将 Shadow DOM 的内容与外层 document DOM 隔离,可以理解为在document中的一个子容器,放置各种组件;
- HTML 模板。 使用 来定义组件模板,使用 作为插槽使用(Vuer一定不陌生);
在一份html文件中的一个web component看起来是这样的:
>插槽内容>
看起来很像Vue吧?接下来让我们一个个demo学习web component。
上手
由于Web Component亲和原生,因此无需其他包的依赖,一个index.html和一个index.js即可体验学习。
我们直接写一个html模板,文章的案例组件统称为
index.html:
>
>
>
>
>
>
>
>
>
>学习Web Component>Web Component是微前端沙盒隔离原理的重要知识>¥25.00>
>
>
>
样式生效:
图片
但是这里如果给一个通用标签的样式,就像这样:
>组件外的P标签>
>
>
>
效果如下:
图片
可以看到组件外的p标签也被影响了,颜色变为红色,而在组件概念中这个样式其实只期望作用于组件本身。这也是样式隔离的概念,而很幸运,Web Component提供了开箱即用的样式隔离方案。
为了不让 里的 CSS 和全局的 CSS 有冲突,我们可以将组件挂在到 Shadow Root 上,再用 Shadow Root 挂到外层的 document DOM 上,这样就可以实现 CSS 的隔离啦:
class Trace extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: "open" });
const templateEle = document.getElementById("trace");
const cloneEle = templateEle.content.cloneNode(true);
this.shadowRoot.appendChild(cloneEle);
}
}
customElements.define("trace-ele", Trace);
从控制台中观察:
图片
而如果有多个组件本质其实就是在document中有多个Shadow Root。
整个DOM架构图是这样的:
图片
Shadow DOM 的一大优点是能将 DOM 结构、样式、行为与 Document DOM 隔离开,非常适合做组件的封装,因此它能成为 Web Component 的重要组成部分之一。
Props
与Vue、React一样,Web Component也提供了父传子的形式。
index.html:
> .title').textContent = this.getAttribute('name');
cloneEle.querySelector('.container " data-textnode-index-1701072719744="600" data-index-1701072719744="4133" data-index-len-1701072719744="4133" class="" >> .price').textContent = this.getAttribute('version');
cloneEle.querySelector('.container " data-textnode-index-1701072719744="607" data-index-1701072719744="4226" data-index-len-1701072719744="4226" class="" >> .desc').textContent = this.getAttribute('desc');
this.shadowRoot.appendChild(cloneEle);
}
}
customElements.define("trace-ele", Trace);
搞定~
Slot
HTML 模板的另一个好处是可以像 Vue 一样使用 。比如,现在我们可以在这个 最下面添加一个插槽:
>
>组件中的P标签>
>
>
>
>
>
...
>
>插槽内容>