Conception multi-onglets Umi4.0

Dans le développement normal du système en arrière-plan, il est souvent nécessaire de mettre en cache certaines pages précédemment ouvertes pour une utilisation facile. Plusieurs onglets sont utilisés pour gérer les pages, comme illustré dans la figure suivanteimage

Cela fait un moment que la version Umi4.0 est sortie.Bien sûr, le nouveau framework doit apprendre de nouvelles fonctionnalités et fonctions.Depuis qu'Umi4.0 est utilisé react-router6, le routage a été considérablement modifié et la conception multi-onglets nécessite également à réajuster.

L'article est divisé en trois parties

  1. Idées de conception
  2. les problèmes rencontrés
  3. Étendre au routage auto-construit

1. Idées de conception

La raison de la conception de plusieurs onglets est que les routes de framework existantes ne peuvent être ouvertes qu'individuellement.Même s'il existe un keep-alive dans Vue, face à /detail:idune telle route, une seule peut exister à la fois.

La structure multi-onglets est la suivante : route et composant un à un, composant et instance un à plusieurs, instance et onglet un à unimage

L'onglet est construit avec l'instance du composant comme dimension, de sorte que le rendu doit être détourné. La raison pour laquelle plusieurs onglets peuvent détourner le rendu est qu'il s'agit d'un composant de haut niveau qui écoute les modifications de routage pour générer les instances correspondantes. Maintenez vous-même la liste des composants actuellement affichés, générez les instances de composants correspondantes à partir des informations de routage globales fournies par le framework et effectuez le rendu vers le bas. À partir de la configuration de routage, toutes les routes de composants sont des sous-routes de routage multi-onglets.

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

Ensuite, l'idée de code spécifique est la suivante

  1. Obtenez la méthode de génération d'instances de composants à partir des informations de routage fournies par le framework et maintenez une file d'attente de tabulation
  2. Écoutez les changements de route, rejoignez la route lorsqu'elle n'est pas dans la file d'attente, activez-la si elle existe déjà et utilisez display:'none' pour le cache, car il s'agit d'un cache de composants de haut niveau affiché ici, qui est plus maniable . Ce n'est pas un cache intégré comme keepalive.
  3. Obtenir les informations de routage correspondantes pour générer une instance de composant et la rendre vers le bas

Deuxièmement, les problèmes rencontrés

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。

image

Ce n'est pas un composant de réaction. Si vous utilisez des crochets, il y aura render more than one hooksune erreur dans certains cas, vous devez faire attention lorsque vous l'utilisez.

4. Résumé

Ce qui précède est l'idée de conception générale du multi-onglet. Si vous avez des idées, n'hésitez pas à échanger dans la zone de commentaires.

Je suppose que tu aimes

Origine juejin.im/post/7147752724262551565
conseillé
Classement