开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 9 天,点击查看活动详情
1. 背景介绍
因为 Qiankun 要求微应用修改自己 router 的 base,来达到 url 隔离的目的。这就造成使用微应用 router 的方法无法跳回主应用,也就无法直接跳到其他微应用。那么如何解决呢?
2. 解决方案
- 直接用
location.href等方法进行 url 跳转即可。但是这个方案的缺点非常明显,那就是在跳转的时候会“白屏”,这就意味着废了大力气引入了微前端,得到的效果跟用 url 隔离一样。所以明显是不可取的。 - 直接调用
window.history.pushState即可,当然,前提是路由系统底层用的是history模式 - 把主应用的
history以props的形式传给子应用即可 ,接下来子应用需要做的就是把它提供给全局使用。放一段代码大家就一目了然了
import Home from "@/pages/home/index.vue";
import VueRouter from "vue-router";
import Vue from "vue";
const routes = [
{
/**
* path: 路径为 / 时触发该路由规则
* name: 路由的 name 为 Home
* component: 触发路由时加载 `Home` 组件
*/
path: "/",
name: "Home",
component: Home,
}
];
Vue.use(VueRouter);
/**
* 注册路由实例
* 即将开始监听 location 变化,触发路由规则
*/
const router = new VueRouter({
mode: "history",
routes,
})
export default router;
import router from "../router";
// 主应用
const apps = [
/**
* name: 微应用名称 - 具有唯一性
* entry: 微应用入口 - 通过该地址加载微应用,这里我们使用 config 配置
* container: 微应用挂载节点 - 微应用加载完成后将挂载在该节点上
* activeRule: 微应用触发的路由规则 - 触发路由规则后将加载该微应用
* props: 主应用属性传入子应用
*/
{
name: "VueMicroApp1",
entry: "//localhost:8081",
container: "#frame",
activeRule: "/vue1",
/* 将路由注入子应用 */
props: { mainAppRouter: router },
},
];
把主应用的 history 以 props 的形式传给子应用即可,接下来子应用需要做的就是把它提供给全局使用。
// 入口改造
function render(props) {
const { container, maiAppRouter } = props;
app = createApp(App);
if (maiAppRouter) {
/* 用 provide 挂到全局 */
app.provide("maiAppRouter", maiAppRouter);
}
instance = app
.use(store)
.use(router)
.mount(container ? container.querySelector("#app") : "#app");
}
// 组件使用
import { inject } from "vue";
const mainAppRouter = inject("maiAppRouter");
mainAppRouter.push('/'); // 等于 history.push('/')
如果主应用是react不能使用useHistory,因为 useHistory 必须在 React 组件中调用,所以需要换一下,如下:
// 主应用
/* 不能有 hooks,用 createBrowserHistory 替换 */
import { createBrowserHistory } from "history";
const history = createBrowserHistory();
const apps = [
/**
* name: 微应用名称 - 具有唯一性
* entry: 微应用入口 - 通过该地址加载微应用,这里我们使用 config 配置
* container: 微应用挂载节点 - 微应用加载完成后将挂载在该节点上
* activeRule: 微应用触发的路由规则 - 触发路由规则后将加载该微应用
* props: 主应用属性传入子应用
*/
{
name: "VueMicroApp1",
entry: "//localhost:8081",
container: "#frame",
activeRule: "/vue1",
/* 将路由注入子应用 */
props: { mainAppRouter: history },
},
];
有bug?想补充?
感谢大家观看这篇文章,有任何问题或想和我交流,请直接留言,
发现文章有不妥之处,也可指出交流,感谢阅读~
最后,求个三连 ~