微前端Micro-app上手体验
前言
最近开发了一个新项目,一期的时候用的是React
,结果二期大改需要用到Vue
的keepalive
功能,一期的内容只存在于项目二期一个页面中的一部分。
由于项目不太复杂,各模块间耦合度不高,就决定引入微前端技术Micro-app
,没想到用起来好多坑,而且该社区不太活跃,还有诸多问题需要小伙伴们帮忙解决。
技术栈
- 基座 React+Ts
- 子应用 Vue3+Ts , React+Ts
数据通信
子应用间的通信
官网上没有提供子应用直接通信的方法,google大法也没有搜索到,于是乎只想到了两种解决办法
利用全局通信
应用传入的数据一定要是对象,所以可以自定义一个属性to
决定数据传给的是去全局还是指定用户
- 子应用app1
window.microApp.setGlobalData({to: 'app2',msg:"子应用app1发送给子应用app2的数据"})
- 子应用app2
function globalDataListener(data: any) {
if (data.to && data.to === "app2") {
console.log("来自子应用间的数据--Vue3", data);
} else {
console.log("来自全局的数据--Vue3", data);
}
}
window.microApp.addGlobalDataListener(globalDataListener, true);
通过基座转发
- 子应用app1
window.microApp.dispatch({to: 'app2',msg:"子应用app1发送给子应用app2的数据"});
- 基座
const dataListener = (data: any) => {
if (data.to && data.to !== "global") {
microApp.setData(data.to, { ...data });
}
console.log("来自子应用的数据---基座", data);
};
microApp.addDataListener("app1", dataListener, true);
- 子应用app2
function globalDataListener(data: any) {
if (data.to && data.to === "app2") {
console.log("来自子应用间的数据--Vue3", data);
} else {
console.log("来自全局的数据--Vue3", data);
}
}
window.microApp.addGlobalDataListener(globalDataListener, true);
基座应用向子应用发送数据
官网上有两种写法:
通过data属性发送数据
在React基座中文件头部一定要加上如下几行代码(注释也要复制),(注释也要复制)!!,当初在官网看漏这句话,就排查很久数据怎么传不进去
/** @jsxRuntime classic */
/** @jsx jsxCustomEvent */
import jsxCustomEvent from '@micro-zoe/micro-app/polyfill/jsx-custom-event'
手动发送数据
microApp.setData("app1", { type: "传给app1的数据" });
当与第一种情况冲突时,手动发送的数据会覆盖data属性的数据
路由跳转
子应用间路由跳转
每个应用的路由实例都是不同的,应用的路由实例只能控制自身,无法影响其它应用。所以我是通过基座做了一个中间层转发,实现子应用间路由跳转
从 app2 跳转到 app1
- app2
const toReact = () => {
window.microApp.dispatch({ path: "/app1" });
};
- 基座
const dataListener = (data: any) => {
console.log("来自子应用app2的数据", data);
if (data.path) {
navigate(data.path);
}
};
基座控制子应用二级以上路由跳转*
官网上描述,在基座中是无法跳转到子应用的二级以上路由的,就很坑。
经过探索发现了可以通过基座监听路由变化,将路径传给子应用手动实现路由的二级跳转
- 基座监听路由变化
useEffect(() => {
microApp.setData("app1", { path: location.pathname });
}, [location.pathname]);
<Link to={"/app1/apple"}>react二级路由apple</Link>
- 子应用手动跳转
const navigate = useNavigate();
const dataListener = (data: any) => {
console.log("来自基座应用的数据1---React", data);
if(data.path){
// 截取子应用路由前缀/app1
const path : string = data.path.slice(5);
console.log(path)
navigate(path)
}
};
useEffect(() => {
window?.microApp.addDataListener(dataListener, true);
}, []);
解决ts类型报错
window.__MICRO_APP_BASE_ROUTE__
在ts项目中,路由配置会出现这样的错误
解决方法是在一下文件中加入如下代码
- Reat --- react-app-env.d.ts
- Vue --- shims-vue.d.ts
declare global {
interface Window {
__MICRO_APP_BASE_ROUTE__: string;
microApp: any;
}
}
// 记得要导出
export {};
window.microApp
解决方法
// @ts-ignore
window?.microApp.addDataListener(dataListener, true);
END
- 文中的情况有更好的解决方法的话,也欢迎各位的指导呀
- 希望这篇文章可以帮助到有需要的小伙伴们,有问题可以评论或私信我呀🤞🤞
转载自:https://juejin.cn/post/7277799790288125952