Diseño de múltiples pestañas Umi4.0

En el desarrollo normal del sistema en segundo plano, a menudo es necesario almacenar en caché algunas páginas abiertas previamente para facilitar el funcionamiento. Se utilizan varias pestañas para administrar las páginas, como se muestra en la siguiente figura.imagen

Ha pasado un tiempo desde que se lanzó la versión Umi4.0. Por supuesto, el nuevo marco necesita aprender nuevas características y funciones. Desde que se usa Umi4.0 react-router6, el enrutamiento ha cambiado mucho y el diseño de múltiples pestañas también necesita para ser reajustado.

El artículo se divide en tres partes.

  1. Ideas de diseño
  2. problemas encontrados
  3. Ampliar al enrutamiento autoconstruido

1. Ideas de diseño

La razón para diseñar varias pestañas es que las rutas del marco existente solo se pueden abrir de forma individual. Incluso si hay un keep-alive en Vue, cuando se enfrenta a /detail:iduna ruta de este tipo, solo puede existir una al mismo tiempo.

La estructura de varias pestañas es la siguiente: ruta y componente uno a uno, componente e instancia uno a muchos, instancia y pestaña uno a unoimagen

La pestaña se construye con la instancia del componente como la dimensión, por lo que la representación debe ser secuestrada. La razón por la que múltiples pestañas pueden secuestrar el renderizado es porque es un componente de orden superior que escucha los cambios de enrutamiento para generar las instancias correspondientes. Mantenga usted mismo la lista de componentes que se muestran actualmente, genere instancias de componentes correspondientes a partir de la información de enrutamiento global proporcionada por el marco y renderice hacia abajo. Desde la configuración de enrutamiento, todas las rutas componentes son subrutas de enrutamiento de múltiples pestañas.

{
  path: '/',
  //多页签对应的组件
  component: '@/layouts/MultiTagRoute.jsx',
  flatMenu: true,
  routes:[
    //以下是实际路由
    {
      name: '组件1',
      path: '/one',
      component: './one',
      icon: 'cluster',
    },
    {
      name: '组件2',
      path: '/two',
      component: './two',
      icon: 'cluster',
    },
  ]
}
复制代码

Entonces la idea del código específico es la siguiente

  1. Obtenga el método para generar instancias de componentes a partir de la información de enrutamiento proporcionada por el marco y mantenga una cola de pestañas
  2. Escuche los cambios de ruta, únase a la ruta cuando no esté en la cola, actívela si ya existe y use display:'none' para el caché, porque es un caché de componentes de alto nivel que se muestra aquí, que es más maniobrable . No es un caché integrado como Keepalive.
  3. Obtenga la información de enrutamiento correspondiente para generar una instancia de componente y representarla hacia abajo

En segundo lugar, los problemas encontrados

react-router6使用 <Outlet/> 渲染路由,同时还提供了 useOutLet 这个hooks获取当前渲染信息。 useOutLet 这个hook返回的 outlet 比较有意思,它不是传统意义上的类似children的dom结构。使用isValidElement检测为true,但是使用cloneElement向其传递props却不会生效。因此想要传递props,只能按照<Outlet context={{}}/>的方式进行参数传递。 此外umi框架在prolayout里面已经使用了<Outlet/>,因此这里只能使用{outlet}这种方式渲染。

umi还有有一个useAppData方法,可以返回组件实例

declare function useAppData(): {
  routes: Record<id, Route>;
  routeComponents: Record<id, Promise<React.ReactComponent>>;
  clientRoutes: ClientRoute[];
  pluginManager: any;
  rootElement: string;
  basename: string;
  clientLoaderData: { [routeKey: string]: any };
  preloadRoute: (to: string) => void;
};
复制代码

routeComponents里面包含了每一个组件的工厂函数,可以直接使用<Component>进行渲染。这种方式使用props就可以传递参数,可以根据实际情况选择。

监听路由变化使用 useLocation,在多页签里面使用useEffect监听location,此外location也能携带一些参数,用于丰富多页签的功能,例如刷新当前页签、跳转前关闭当前页签,跳转后自动刷新等功能,只要在query参数里面约定好即可。

三、扩展到自建路由

有了上面的设计思路,平时开发中也会遇到自建路由的需求。路由本质就是路径字符串到组件的映射。我们自建路由的配置也应如下

{
  name: '多页签',
  component: React.lazy(() => import('./multiTag')),
  path: '/',
  children: [
    {
      name: '组件A',
      path: '/componentA',
      component: React.lazy(() => import('./componentA')),
    },
    {
      name: '组件B',
      path: '/componentB',
      component: React.lazy(() => import('./componentB')),
    }
  ]
}
复制代码

使用 context 维护全局字符串路径,向下传递自建跳转方法就可以模拟路由跳转,自建的路径信息数据结构与location保持一致就可以。

这里还有一点需要注意的地方,传统异步加载是这样的方式() => import('./componentA'),没有添加React.lazy,这样加载出来的文件会被解析为module。

imagen

No es un componente de reacción.Si usa ganchos, habrá render more than one hooksun error en algunos casos, debe prestar atención al usarlo.

4. Resumen

Lo anterior es la idea de diseño general de múltiples pestañas. Si tiene alguna idea, bienvenido a intercambiar en el área de comentarios.

Supongo que te gusta

Origin juejin.im/post/7147752724262551565
Recomendado
Clasificación