import type { Context } from "@nuxt/types"; import lodash from "lodash"; declare global { interface Window { __MICRO_APP_NAME__: string; __MICRO_APP_BASE_ROUTE__: string; __MICRO_APP_ENVIRONMENT__: boolean; } } function eqBasePath() { return lodash.includes( lodash.toLower(lodash.trim(window.location.pathname, '/')), lodash.toLower(lodash.trim(window.__MICRO_APP_BASE_ROUTE__, '/')), ); } /** * 拦截 非注册 pathname 下 路由跳转 * @export * @param {Context} ctx * @param {boolean} [popstate=true] */ export function microRewriteBeforeEach(ctx: Context, popstate = true) { // 解决 微应用模式下 keepAlive 路由会改变 if (window.__MICRO_APP_ENVIRONMENT__) { if (!eqBasePath()) { throw new Error( '微应用加载错误 __MICRO_APP_BASE_ROUTE__ 和 当前 pathname 不一致', ); } ctx.app.router.beforeEach((to, from, next) => { // 页面 根节点 第一次 app.$el 为 null const element: HTMLDivElement = lodash.get(window, '$nuxt.$el'); // 页面元素是否和dom树链接 const isConnected = lodash.get(element, 'isConnected'); // 页面是否处于显示状态ctx. const elementShow = isConnected && lodash.gt(lodash.get(element, 'offsetHeight', 0), 0); const toNext = lodash.isNil(element) || lodash.every( [ isConnected, elementShow, // 当前路由是否是属于微应用路径下 eqBasePath(), ], Boolean, ); console.warn(`【 ${window.__MICRO_APP_NAME__} 】beforeEach`, { ctx, to, from, element, toNext, isConnected, elementShow, pathname: lodash.toLower(window.location.pathname), __MICRO_APP_BASE_ROUTE__: lodash.toLower( window.__MICRO_APP_BASE_ROUTE__, ), }); // 首次加载&页面显示路由放行 if (toNext) { return next(); } console.warn( `【 ${window.__MICRO_APP_NAME__} 】微应用模式下非当前引用路由切换 已终止`, ); }); ctx.app.router.afterEach((to, from) => { if (popstate) { window.dispatchEvent(new PopStateEvent('popstate', {})); } }); } }