Garfish.router

用于微前端下的应用间的路由跳转,提供路守卫能力,在路由变化时触发相应hook,帮助用户更加精确的控制路由变化,灵活地支持各类业务场景。

路由是微前端中重要且复杂的模块。在微前端应用下,子应用既可作为独立应用运行在自己的路由系统下,又可作为子应用嵌入在主应用下加载,为了实现两种模式的无缝切换,Garfish 实现了一套路由机制保证用户在这两种模式中平滑过渡,你可以在 Garfish 路由机制 中了解详细设计。

INFO

在阅读下面 API 介绍之前,你需要了解和保证一些配置规范。

  1. 你需要了解的:
  • 目前 Garfish 路由系统通过命名空间(即子应用 basename)来避免应用间的路由冲突;
  • 目前 Garfish 路由系统仅支持主应用的 history 路由模式,原因是 hash 路由无法作为子应用的基础路由;
  • 不要使用根路由作为子应用的激活条件,否则该应用在任何路径下都会激活,且应用间可能会产生冲突;
  • 子应用在 provider 中的 render 函数拿到的 basename = 主应用的 basename + activeWhen
  1. 你需要配置的:
  • 请将 providerrender 函数接收到的 basename 设置为子应用的 basename如何配置

Garfish.router

Garfish.router 是 Garfish 实例上的属性,由 Garfish 路由系统提供。该属性上提供应用间路由跳转的方法、路由导航守卫钩子函数以及路由相关配置信息。其类型定义如下:

Type

interface Garfish {
    router: RouterInterface;
    apps: Record<string, interfaces.App>;
}

interface RouterInterface {
    push: ({ path, query, basename}: {
        path: string;
        basename?: string;
        query?: {
            [key: string]: string;
        };
    }) => void;
    replace: ({ path, query, basename}: {
        path: string;
        basename?: string;
        query?: {
            [key: string]: string;
        };
    }) => void;
    beforeEach: (hook: RouterHook) => void;
    afterEach: (hook: RouterHook) => void;
    registerRouter: (Apps: interfaces.AppInfo | Array<interfaces.AppInfo>) => void;
    routerChange: (hook: RouterChange) => void;
    setRouterConfig: typeof setRouterConfig;
    listenRouterAndReDirect: ({ apps, basename, autoRefreshApp, active, deactive, notMatch}: Options$1) => void;
    routerConfig: Options$1;
}

默认值

Garfish.router.push

路由导航方法。

Type

push: ({ path, query, basename}: {
      path: string;
      basename?: string;
      query?: {
          [key: string]: string;
      };
  }) => void;

参数

  • path

    要跳转的路由,string,必选。

  • basename

    设置跳转的基础路由,string,非必选。

  • query

    路由携带的查询参数,Record<string, string>,非必选。

示例

import Garfish from 'garfish';

// 跳转 vue-a 应用:
Garfish.router.push({
  path: '/vue-a'
});

// 跳转 react-b 应用详情页:
Garfish.router.push({
  path: "/react-b/detail",
  query: { id: "002" },
});

说明

  1. Garfish.router.push() 方法默认会携带上全局 basename 作为跳转前缀,若使用框架自身路由进行跳转,请记得主动添加basename 跳转前缀。下面两种跳转方式等价:
Garfish.router.push({ path: '/react-b' });
navigate('/examples/react-b'); // navigate 为 react-router-dom v6 跳转方法
  1. 此方法会向 history 栈添加新的记录,点击浏览器后退按钮后能正常返回上一个页面;

  2. 若跳转子应用的子路由,使用 Garfish.router.push() 方法跳转将触发子应用子路由视图更新。另外若关闭 autoRefreshApp 选项,则将只能使用 Garfish.router 进行跳转子应用子路由,但子应用一级路由仍将可使用框架路由跳转。

  3. 本 api 可以在 react-router-prompt 触发多次时,配合 autoRefreshApp 配置。关闭其他跳转方法触发子应用刷新组件,可限制 prompt 触发多次或子应用额外卸载多次的场景。

INFO

由于目前主流框架并不是通过监听路由变化来触发组件的更新的。在跳转子应用子路由时,若直接使用 history.pushState 将不会触发对应路由的组件更新,请使用 Garfish.router 提供的方法进行跳转。

Garfish.router.replace

路由导航方法。

Type

replace: ({ path, query, basename}: {
      path: string;
      basename?: string;
      query?: {
          [key: string]: string;
      };
  }) => void;

参数

  • path

    要跳转的路由,string,必选。

  • basename

    设置跳转的基础路由,string,非必选。

  • query

    路由携带的查询参数,Record<string, string>,非必选。

示例

import Garfish from 'garfish';
// 跳转 react-a 应用:
Garfish.router.replace({
  path: '/react-a'
});

说明

  1. Garfish.router.replace() 方法与 Garfish.router.push() 方法类似,唯一的区别是:它不会向 history 添加新记录,而是跟替换掉当前的 history 记录;
  2. 其它参数请参考 Garfish.router.push()

Garfish.router.beforeEach

触发时机

  • 全局路由守卫,在路由跳转后子应用挂载前触发。

Type

beforeEach: (hook: RouterHook) => void;

type RouterHook = (
  to: CurrentRouterInfo,
  from: CurrentRouterInfo,
  next,
) => void;

export interface CurrentRouterInfo {
  fullPath: string;
  path: string;
  query: Object;
  state: Object;
  matched: Array<interfaces.AppInfo>;
}

参数

  • to :即将要进入的目标路由信息。

  • from :即将离开的路由信息。

  • next :阻塞执行回调。

示例

import Garfish from 'garfish';
Garfish.router.beforeEach((to, from, next) => {
  next();
});

Garfish.run({...})

Garfish.router.afterEach

触发时机

  • 全局路由守卫,在路由跳转后子应用挂载后触发。

Type

afterEach: (hook: RouterHook) => void;

type RouterHook = (
  to: CurrentRouterInfo,
  from: CurrentRouterInfo,
  next,
) => void;

export interface CurrentRouterInfo {
  fullPath: string;
  path: string;
  query: Object;
  state: Object;
  matched: Array<interfaces.AppInfo>;
}

参数

  • to :即将要进入的目标路由信息。

  • from :即将离开的路由信息。

  • next :阻塞执行回调。

示例

import Garfish from 'garfish';
Garfish.router.afterEach((to, from, next) => {
  next();
});

Garfish.run({...})

Garfish.router.routerChange

触发时机

  • 全局路由守卫,在路由发生变化子应跳转前触发。

Type

afterEach: (path: string) => void;

参数

  • path :跳转到的location.pathname

示例

import Garfish from 'garfish';
Garfish.router.routerChange(path => {
  console.log(path);
});

Garfish.run({...})
TIP

请注意:

  1. Garfish.router.beforeEachGarfish.router.afterEachGarfish.router.routerChange 均属于 Garfish 提供的路由守卫钩子,将在每次在路由变化后触发。
  2. Garfish.router.beforeEachGarfish.router.afterEachGarfish.router.routerChange全局唯一的,如果设置多次,那么只有最后执行的是有效的。对它们的使用应该需要一定的约定,避免多次注册导致互相覆盖。
  3. 请将路由守卫注册放在 Garfish.run 前执行,否则将无法接收到首次加载时的路由钩子;
  4. 若跳转新的子应用,则 Garfish.router.beforeEach 将在子应用加载前触发,Garfish.router.afterEach 将在子应用加载后触发。此时路由均已发生变化;
  5. next 函数可为异步函数,微前端渲染流程将被阻塞直至 next 函数被 resolve。
  6. 在子应用间跳转时,若使用了路由守卫钩子,请确保 next 函数被执行,否则将导致 Garfish 内部子应用渲染逻辑被阻塞;
  7. 子应用内路由跳转不受 next 函数调用的影响;