路由和菜单

路由和菜单是组织起一个应用的关键骨架,pro 中的路由为了方便管理,使用了中心化的方式,在 router.config.js 统一配置和管理。

基本结构

在这一部分,脚手架通过结合一些配置文件、基本算法及工具函数,搭建好了路由和菜单的基本框架,主要涉及以下几个模块/功能:

  • 路由管理 通过约定的语法根据在 router.config.js 中配置路由。
  • 菜单生成 根据路由配置来生成菜单。菜单项名称,嵌套路径与路由高度耦合。
  • 面包屑 组件 PageHeader 中内置的面包屑也可由脚手架提供的配置信息自动生成。
    下面简单介绍下各个模块的基本思路,如果你对实现过程不感兴趣,只想了解应该怎么实现相关需求,可以直接查看需求实例

路由

目前脚手架中所有的路由都通过 router.config.js 来统一管理,在 umi 的配置中我们增加了一些参数,如 nameiconhideChildrenInMenuauthority,来辅助生成菜单。其中:

  • nameicon分别代表生成菜单项的文本和图标。
  • hideChildrenInMenu 用于隐藏不需要在菜单中展示的子路由。用法可以查看 分步表单 的配置。
  • hideInMenu 可以在菜单中不展示这个路由,包括子路由。效果可以查看 exception/trigger页面。
  • authority 用来配置这个路由的权限,如果配置了将会验证当前用户的权限,并决定是否展示。

你可能注意到配置中的 name 和菜单实际展示的不同,这是因为我们使用了全球化组件的原因,具体参见 i18n

菜单

菜单根据 router.config.js 生成,具体逻辑在 src/models/menu.js 中的 formatter 方法实现。

如果你的项目并不需要菜单,你可以直接在 BasicLayout 中删除 SiderMenu 组件的挂载。并在 src/layouts/BasicLayout 中设置 const MenuData = []

从服务器请求菜单

只需在 models/menu 中发起 http 请求,menuData 是一个 json 数组。只需服务器返回类似格式的 json 即可。

  1. [
  2. {
  3. path: '/dashboard',
  4. name: 'dashboard',
  5. icon: 'dashboard',
  6. children: [
  7. {
  8. path: '/dashboard/analysis',
  9. name: 'analysis',
  10. exact: true,
  11. },
  12. {
  13. path: '/dashboard/monitor',
  14. name: 'monitor',
  15. exact: true,
  16. },
  17. {
  18. path: '/dashboard/workplace',
  19. name: 'workplace',
  20. exact: true,
  21. },
  22. ],
  23. }
  24. ...
  25. ]

注意 path 必须要在 routre.config.js 中定义。(约定式路由不需要,只需页面真实有效即可)

面包屑

面包屑由 PageHeaderWrapper 实现,MenuContext 将 根据 MenuData 生成的 breadcrumbNameMap 通过 props 传递给了 PageHeader,如果你要做自定义的面包屑,可以通过修改传入的 breadcrumbNameMap 来解决。

breadcrumbNameMap 示例数据如下:

  1. {
  2. '/': { path: '/', redirect: '/dashboard/analysis', locale: 'menu' },
  3. '/dashboard/analysis': {
  4. name: 'analysis',
  5. component: './Dashboard/Analysis',
  6. locale: 'menu.dashboard.analysis',
  7. },
  8. ...
  9. }

需求实例

上面对这部分的实现概要进行了介绍,接下来通过实际的案例来说明具体该怎么做。

菜单跳转到外部地址

你可以直接将完整 url 填入 path 中,框架会自动处理。

  1. {
  2. path: 'https://pro.ant.design/docs/getting-started-cn',
  3. target: '_blank', // 点击新窗口打开
  4. name: "文档",
  5. }

新增页面

脚手架默认提供了两种布局模板:基础布局 - BasicLayout 以及 账户相关布局 - UserLayout

基础布局

账户相关布局

如果你的页面可以利用这两种布局,那么只需要在路由配置中增加一条即可:

  1. // app
  2. {
  3. path: '/',
  4. component: '../layouts/BasicLayout',
  5. routes: [
  6. // dashboard
  7. { path: '/', redirect: '/dashboard/analysis' },
  8. { path :'/dashboard/test',component:"./Dashboard/Test"},
  9. ...
  10. },

加好后,会默认生成相关的路由及导航。

新增布局

在脚手架中我们通过嵌套路由来实现布局模板。router.config.js 是一个数组,其中第一级数据就是我们的布局,如果你需要新增布局可以再直接增加一个新的一级数据。

  1. module.exports = [
  2. // user
  3. {
  4. path: '/user',
  5. component: '../layouts/UserLayout',
  6. routes:[...]
  7. },
  8. // app
  9. {
  10. path: '/',
  11. component: '../layouts/BasicLayout',
  12. routes:[...]
  13. },
  14. // new
  15. {
  16. path: '/new',
  17. component: '../layouts/new_page',
  18. routes:[...]
  19. },
  20. ]

在菜单中使用自定义的 icon

由于 umi 的限制,在 router.config.js 是不能直接只是用组件的,Pro 中暂时支持 使用 ant.design 本身的 icon type,和传入一个 img 的 url。只需要直接在 icon 属性上配置即可,如果是个 url,Pro 会自动处理为一个 img 标签。

如果这样还不能满足需求,可以自定义 getIcon 方法。

如果你想使用 iconfont 的图标,你可以使用ant.desgin的自定义图标.

带参数的路由

脚手架默认支持带参数的路由,但是在菜单中显示带参数的路由并不是个好主意,我们并不会自动的帮你注入一个参数,你可能需要在代码中自行处理。

  1. {
  2. path: '/dashboard/:page',
  3. hideInMenu:true,
  4. name: 'analysis',
  5. component: './Dashboard/Analysis',
  6. },

你可以通过以下代码来跳转到这个路由:

  1. import router from 'umi/router';
  2. router.push('/dashboard/anyParams');
  3. //or
  4. import Link from 'umi/link';
  5. <Link to="/dashboard/anyParams">go</Link>;

在路由组件中,可以通过this.props.match.params 来获得路由参数。

更多详细内容请参见:umi#路由