- 运行模式
- 保活模式
- 单例模式
- 重建模式
- 生命周期改造
- 改造入口函数:
- 应用间通信
- 原理
- props 通信
- 主应用可以通过 props 注入数据和方法:
- 子应用可以通过 $wujie 对象来获取数据:
- window 通信
- 主应用调用子应用的全局数据:
- 子应用调用主应用的全局数据:
- 中心化 EventBus 通信机制
- 获取 bus 实例:
- 通信方法:
运行模式
官方地址:https://wujie-micro.github.io/doc/guide/mode.html
在微前端框架中,子应用放置在主应用页面中随着主应用页面的打开和关闭反复的激活和销毁,而在无界微前端框架中子应用是否保活以及是否进行生命周期的改造会进入完全不同的处理流程
保活模式
子应用的 alive
设置为true时进入保活模式,内部的数据和路由的状态不会随着页面切换而丢失。
//设置子应用demo
setupApp({name: "demo",... alive: boolean, /** 子应用保活,state不会丢失 */...
});
在保活模式下,子应用只会进行一次渲染,页面发生切换时承载子应用dom的webcomponent会保留在内存中,当子应用重新激活时无界会将内存中的webcomponent重新挂载到容器上
保活模式下改变 url 子应用的路由不会发生变化,需要采用 通信 的方式对子应用路由进行跳转
注意
保活的子应用的实例不会销毁,子应用被切走了也可以响应 bus 事件,非保活的子应用切走了监听的事件也会全部销毁,需要等下次重新 mount 后重新监听。
单例模式
子应用的alive为false且进行了生命周期改造
时进入单例模式。
子应用页面如果切走,会调用window.__WUJIE_UNMOUNT销毁子应用当前实例,子应用页面如果切换回来,会调用window.__WUJIE_MOUNT渲染子应用新的子应用实例
在单例式下,改变 url 子应用的路由会发生跳转到对应路由
如果主应用上有多个菜单栏用到了子应用的不同页面,在每个页面启动该子应用的时候将name设置为同一个,这样可以共享一个wujie实例,承载子应用js的iframe也实现了共享,不同页面子应用的url不同,切换这个子应用的过程相当于:销毁当前应用实例 => 同步新路由 => 创建新应用实例
重建模式
子应用既没有设置为保活模式,也没有进行生命周期的改造则进入了重建模式,每次页面切换不仅会销毁承载子应用dom的webcomponent,还会销毁承载子应用js的iframe,相应的wujie实例和子应用实例都会被销毁
重建模式下改变 url 子应用的路由会跳转对应路由,但是在 路由同步 场景并且子应用的路由同步参数已经同步到主应用url上时则无法生效,因为改变url后会导致子应用销毁重新渲染,此时如果有同步参数则同步参数的优先级最高
生命周期改造
官方地址:https://wujie-micro.github.io/doc/guide/start.html#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E6%94%B9%E9%80%A0
改造入口函数:
- 将子应用路由的创建、实例的创建渲染挂载到window.__WUJIE_MOUNT函数上
- 将实例的销毁挂载到window.__WUJIE_UNMOUNT上
- 如果子应用的实例化是在异步函数中进行的,在定义完生命周期函数后,请务必主动调用无界的渲染函数 window.__WUJIE.mount()(见 vite 示例)
let app;function renderApp() {app = new Vue({router,store,render: (h) => h(App),});app.$mount("#app");
}function destroyApp() {app.$destroy();
}if (window.__POWERED_BY_WUJIE__) {window.__WUJIE_MOUNT = renderApp;window.__WUJIE_UNMOUNT = destroyApp;// // Vite 需要主动调用 wujie 的渲染函数// window.__WUJIE.mount();
} else {renderApp();
}
应用间通信
无界提供多种通信方式:
- props 数据注入、
- window.parent 直接通信、
- 去中心化 EventBus 通信机制
原理
- 子应用 js 在和主应用同域的 iframe 内运行,所以 window.parent 可以直接拿到主应用的 window 对象来进行通信
- 主应用可以向子应用注入 props 对象,里面可以注入数据和方法供子应用调用
- 内置的 EventBus 去中心化通信方案可以让应用之间方便的直接通信
props 通信
主应用可以通过 props 注入数据和方法:
<WujieVue name="xxx" url="xxx" :props="{ data: xxx, methods: xxx }"></WujieVue>
子应用可以通过 $wujie
对象来获取数据:
const props = window.$wujie?.props;
<button @click="props.methods()">按钮</button>
window 通信
由于子应用运行的 iframe 的 src 和主应用是同域的,所以相互可以直接通信。
主应用调用子应用的全局数据:
window.document.querySelector("iframe[name=子应用id]").contentWindow.xxx;
<template><div style="width: 300px; margin: 0 0 0 -2px; border: 2px solid #ebebeb; background: #f8f8f8;"><button @click="getVueChild1Data">获取子应用数据</button><WujieVue width="100%" height="100%" name="vue3Child1" :url="vue3Child1Url" :props="{ globalData: 'globalData20240301', methods: globalData20240301Nethods }"/></div>
</template><script> ... getVueChild1Data(){console.log('getVueChild1Data')console.log(window.document.querySelector("iframe[name=vue3Child1]"))}
</script>
注意子应用id一定要一致
子应用调用主应用的全局数据:
window.parent.xxx;
中心化 EventBus 通信机制
wujie 提供一套去中心化的通信方案,主应用和子应用、子应用和子应用都可以通过这种方式方便的进行通信, 详见 api: https://wujie-micro.github.io/doc/api/bus.html#bus
获取 bus 实例:
// 主应用
import WujieVue from "wujie-vue";
const { bus } = WujieVue;// 子应用
window.$wujie?.bus
通信方法:
// 监听事件
bus.$on("事件名字", (arg1, arg2, ...) => {});
// 发送事件
bus.$emit("事件名字", arg1, arg2, ...);
// 取消事件监听
bus.$off("事件名字", (arg1, arg2, ...) => {});