优点:原生组件,不需要框架,性能好代码少。
缺点:兼容性问题
组件化好处: 高内聚、可重用、可组合
核心三项技术
- Custom elements:一组JavaScript API,允许您定义custom elements及其行为,然后可以在您的用户界面中按照需要使用它们
- Shadow DOM:一组JavaScript API,用于将封装的“影子”DOM树附加到元素(与主文档DOM分开呈现)并控制其关联的功能。通过这种方式,您可以保持元素的功能私有,这样它们就可以被脚本化和样式化,而不用担心与文档的其他部分发生冲突。
- HTML templates:
<template>
和<slot>
元素使您可以编写不在呈现页面中显示的标记模板。然后它们可以作为自定义元素结构的基础被多次重用。
生命周期回调
- 定义在自定义元素的类定义中的特殊回调函数,影响其行为:
connectedCallback
:当自定义元素第一次被连接到文档 DOM 时被调用。disconnectedCallback
:当自定义元素与文档 DOM 断开连接时被调用。adoptedCallback
:当自定义元素被移动到新文档时被调用。attributeChangedCallback
:当自定义元素的一个属性被增加、移除或更改时被调用。
我们实现一个自定义的button组件
HTML templates
组件的名字必须以中划线分割,避免与native标签冲突
新建index.html
<my-button type="primary">这是一个按钮</my-button>
<template id="btn">
<button class="my-btn">
<slot>这是一个按钮</slot>
</button>
</template>
template
中的内容是我们定义的button
组件的样子。slot
可以获取自定义组件中的内容,插入到模板对应的位置
新建zfButton.js
- shadow DOM 可以实现真正的隔离机制
class myButton extends HTMLElement{
constructor(){
super();
// 创建影子
let shadow = this.attachShadow({mode:'open'});
let btn = document.getElementById('btn');
// 拷贝模板
let cloneTemplate = btn.content.cloneNode(true);
const style = document.createElement('style');
const types = {
'primary':{
backgroundColor:'#409eff',
color:'#fff'
},
'default':{
backgroundColor:'#c8c9cc',
color:'#fff'
}
}
const btnType = this.getAttribute('type') || 'default';
style.innerHTML = `
.my-btn {
outline:none;
border:none;
border-radius:4px;
display:inline-block;
cursor:pointer;
padding:6px 20px;
background:var(--background-color,${types[btnType].backgroundColor});
color:var(--text-color,${types[btnType].color});
}
`
shadow.appendChild(style);
shadow.appendChild(cloneTemplate);
}
}
- customElement
window.customElements.define('my-button',myButton)
定义自定义组件,它使开发者能够将 HTML 页面的功能封装为 custom elements(自定义标签)来进行功能的复用和抽象
组件展示
这个时候按是一个shadow DOM,样式是隔离的。
如果出现这样的问题,请起个服务。
webComponent和微前端的关系
可以将微应用都被封装在自定义标签wed-sandbox的shadowDOM中。不过这里我们需要注意的是:加载子应用会存在资源跨域的问题,这里不同于上面的本地服务问题,而是不同子应用资源域名协议不同造成的,所以需要单独拿资源处理。(qiankun import-html-entry里做了很完备的处理)
关于如何构建使用webCompoent构建微前端的代码示例,已经放在个git上,需要的可以直接拉取,一键跑通。
写在最后:由于webComponent并不是重点,本篇文章只是简单介绍,下一篇我们讲介绍如何使用webpack5的联邦模块构建微前端,请尽请期待
微前端从零到剖析qiankun源码 -- Module Federation的玩法!