配置路由菜单

4,233 阅读4分钟

比如说需要配置个大概下面效果的菜单。

新建相关页面模块

首先,需要在 src/pages 下新建所需页面的模块。

直接在 route.config.ts 中配置路由

由于使用的是 umi 内置的 layout,所以在 umi 中无需去关心左侧菜单栏的设计,直接配置好相对于的路由,它会自动帮你生成相对于的菜单。

下面直接贴上 routes 的配置数据,需注意其书写格式,否则可能会造成菜单栏无法展示出来的问题。

const route = [
  {
    name: '登录',
    path: '/login',
    component: '@/pages/Login',
    hideInMenu: true,
    layout: false,
  },
  {
    path: '/404',
    component: '@/pages/404Page',
  },
  {
    path: '/',
    redirect: '/postManager',
  },
  {
    name: '帖子管理',
    path: '/postManager',
    component: '@/layouts',
    icon: 'home',
    hideChildrenInMenu: true,
    routes: [
      {
        name: '帖子管理',
        path: '/postManager',
        component: '@/pages/PostManager/List',
      },
      {
        name: '帖子详情',
        path: '/postManager/detail',
        component: '@/pages/PostManager/PostDetail',
      },
      {
        redirect: '/404',
      },
    ],
  },
  {
    name: '委托管理',
    icon: 'home',
    path: '/entrustManager',
    component: '@/layouts',
    routes: [
      {
        name: '全部委托',
        path: '/entrustManager/all',
        component: '@/pages/EntrustManager/AllEntrust',
      },
      {
        name: '全部委托详情',
        path: '/entrustManager/all/detail',
        component: '@/pages/EntrustManager/EntrustDetail',
        hideInMenu: true,
      },
      {
        name: '已同步委托',
        path: '/entrustManager/synced',
        component: '@/pages/EntrustManager/SyncedEntrust',
      },
      {
        name: '已同步委托详情',
        path: '/entrustManager/synced/detail',
        component: '@/pages/EntrustManager/EntrustDetail',
        hideInMenu: true,
      },
      {
        redirect: '/404',
      },
    ],
  },
  {
    name: '用户管理',
    path: '/userManager',
    component: '@/layouts',
    icon: 'home',
    hideChildrenInMenu: true,
    routes: [
      {
        name: '用户管理',
        path: '/userManager',
        component: '@/pages/UserManager/List',
      },
      {
        name: '帖子详情',
        path: '/userManager/detail',
        component: '@/pages/UserManager/UserDetail',
      },
      {
        redirect: '/404',
      },
    ],
  },
  {
    redirect: '/404',
  },
];

export default route;

注意点:

  • 有一级菜单但是不需要展示二级菜单,如上面的帖子管理。使用 hideChildrenInMenu: true 进行隐藏,
  • 有一级菜单且也有二级菜单,但其下面的部分菜单不需要展示,使用 hideInMenu: true 进行隐藏。如上面的那些委托详情。
  • 不需要展示到菜单栏的路由,如登录页,使用 hideInMenu: true 进行隐藏。(umilayout 默认是会把配置的全部路由都自动生成为左侧菜单,所以菜单的显隐需要自己去控制)。
  • 上面登录页这个设置后,虽然左侧菜单栏没有登录的菜单了,但是如果我们访问登录页的话,会看到它展示在 layoutcontent 中(简单说就是还是存在菜单栏),如何做到页面全屏展示?这个时候就还需要配置 layout: false

路由优化

看上面路由的配置信息,没有几个页面,就已经快上百行了,如果一个项目的模块比较多的话,能达到成百上千不是问题,所以可以针对这个进行优化一下。

我的思路是:

将各模块的路由配置在各自的页面模块下,如上面的的用户管理的路由就配置在 src/pages/UserManager 目录下。

然后在 config/routes.config.ts 文件中统一导入合并,然后再统一导出赋值给 umiroute 配置

以上面例子三个模块为例,可分别在其对应的模块下新建三个路由配置文件。

注意导出的方式,是以 nodejs 的方式导出的。所有的路由配置文件都是 cmd 环境的,并不是 es6 环境的,因为下面需要使用 nodejs 的一些 API 来读取这些配置文件的配置内容进行整合处理。

config/routes.config.ts 文件下使用 nodejs 的方式进行统一导入。然后再在这个文件整合所有路由统一导出。

/*
 * @Description: 路由配置文件
 * @Author: kivet
 * @Date: 2022-01-29 13:52:34
 * @LastEditTime: 2022-01-29 17:56:43
 */

const path = require('path');
const fs = require('fs');

/**
 * 读取 pages 目录下所有页面模块的路由配置,注:路由配置文件名,必须以 route[.***].(ts|js) 的格式命名
 * @param dir 目录
 * @param useSubDir 是否读取子目录
 */
const generateRoutes = (pagesDir: string, useSubDir: boolean) => {
  const routeFileList: any = [];

  const readRouteFileList = (_dir: string, _useSubDir: boolean) => {
    const files = fs.readdirSync(_dir);
    files.forEach((item: any) => {
      // 生成
      const filePath = path.join(_dir, item);
      const stat = fs.statSync(filePath);
      // 判断是否为目录
      if (stat.isDirectory() && _useSubDir) {
        readRouteFileList(path.join(_dir, item), _useSubDir);
      } else {
        const reg = RegExp(/route(.*).ts|js/);
        if (reg.test(filePath)) {
          routeFileList.push(filePath);
        }
      }
    });
  };

  // 递归读取路由配置文件
  readRouteFileList(pagesDir, useSubDir);
  const routes = routeFileList.map((item: string) => require(item));
  return routes;
};

/**
 * 读取pages目录下路由文件,自动生成路由表
 */
const routes = generateRoutes(path.join(__dirname, '../src/pages'), true);

export default [
  {
    name: '登录',
    path: '/login',
    component: '@/pages/Login',
    hideInMenu: true,
    layout: false,
  },
  {
    path: '/404',
    component: '@/pages/404Page',
  },
  {
    path: '/',
    redirect: '/postManager',
  },
  ...routes,
  {
    redirect: '/404',
  },
];

核心代码即使上面的 generateRoutes() 函数,他是使用的 nodejs 的方式去读取 pages 目录下所有以 route[.***].(ts|js) 的格式命名的路由配置文件的数据。

这样写的好处就是,之后你新增其它模块的路由配置时,不需要每新增一个就得在这里导入整合一次,直接一步到位,之后就可以随便加新的模块了。


返回目录文档