likes
comments
collection
share

微前端从零到剖析qiankun源码 -- Web Components的玩法!

作者站长头像
站长
· 阅读数 11

优点:原生组件,不需要框架,性能好代码少。 缺点:兼容性问题

组件化好处: 高内聚、可重用、可组合

微前端从零到剖析qiankun源码 -- Web Components的玩法!

核心三项技术

  • 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 可以实现真正的隔离机制 微前端从零到剖析qiankun源码 -- Web Components的玩法!
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(自定义标签)来进行功能的复用和抽象

组件展示

微前端从零到剖析qiankun源码 -- Web Components的玩法!

这个时候按是一个shadow DOM,样式是隔离的。

如果出现这样的问题,请起个服务。

微前端从零到剖析qiankun源码 -- Web Components的玩法!

webComponent和微前端的关系

可以将微应用都被封装在自定义标签wed-sandbox的shadowDOM中。不过这里我们需要注意的是:加载子应用会存在资源跨域的问题,这里不同于上面的本地服务问题,而是不同子应用资源域名协议不同造成的,所以需要单独拿资源处理。(qiankun  import-html-entry里做了很完备的处理)

微前端从零到剖析qiankun源码 -- Web Components的玩法!

关于如何构建使用webCompoent构建微前端的代码示例,已经放在个git上,需要的可以直接拉取,一键跑通。

写在最后:由于webComponent并不是重点,本篇文章只是简单介绍,下一篇我们讲介绍如何使用webpack5的联邦模块构建微前端,请尽请期待微前端从零到剖析qiankun源码 -- Module Federation的玩法!