003-ant design pro 路由和菜单

一、概述

  参看地址:https://pro.ant.design/docs/router-and-nav-cn

二、原文摘要

  路由和菜单是组织起一个应用的关键骨架,我们的脚手架提供了一些基本的工具及模板,帮助你更方便的搭建自己的路由/菜单。

  如果你想了解更多关于 browserHistory 和 hashHistory,请参看 构建和发布

注意:我们的脚手架依赖 [email protected],路由方面是基于 [email protected] 的实现,在写法以及 API 上与之前的版本有较大不同,所以,在开始前你需要具备一些相关的基础知识。这里给出几篇关键文档:

2.1、基本结构

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

  • 路由生成 结合路由信息的配置文件和预设的基本算法,提供了在不同层级文件中自动生成路由列表的能力。
  • 菜单生成 由确定数据结构的菜单配置文件生成,其中的菜单项名称,嵌套路径与路由有一定关联关系。
  • 面包屑 组件 PageHeader 中内置的面包屑也可由脚手架提供的配置信息自动生成。

简单介绍下各个模块的基本思路。

2.1.1、路由

目前在脚手架中,除了顶层路由,其余路由列表都是自动生成,其中最关键的就是中心化配置文件 src/common/router.js,它的主要作用有两个:

  • 配置路由相关信息。如果只考虑生成路由,你只需要指定每条配置的路径及对应渲染组件。
  • 输出路由数据,并将路由数据(routerData)挂载到每条路由对应的组件上。

这样我们得到一个基本的路由信息对象,它的结构大致是这样:

{
  ‘/dashboard/analysis‘: {
    component: DynamicComponent(),
    name: ‘分析页‘,
  },
  ‘/dashboard/monitor‘: {
    component: DynamicComponent(),
    name: ‘监控页‘,
  },
  ‘/dashboard/workplace‘: {
    component: DynamicComponent(),
    name: ‘工作台‘,
  },
}

为了帮助自动生成路由,在 src/utils/utils.js 中提供了工具函数 getRoutes,它接收两个参数:当前路由的 match 路径及路由信息 routerData,主要完成两个工作:

  • 筛选路由信息,筛选的算法为只保留当前 match.path 下最邻近的路由层级(更深入的层级留到嵌套路由中自行渲染),举个例子(每条为一个 route path):
// 当前 match.path 为 /
/a                 // 没有更近的层级,保留
/a/b               // 存在更近层级 /a,去掉
/c/d               // 没有更近的层级,保留
/c/e               // 没有更近的层级,保留
/c/e/f             // 存在更近层级 /c/e,去掉
  • 自动分析路由 exact 参数,除了下面还有嵌套路由的路径,其余路径默认设为 exact。

经过 getRoutes 处理之后的路由数据就可直接用于生成路由列表:

// src/layouts/BasicLayout.js
getRoutes(match.path, routerData).map(item => (
  <Route
    key={item.key}
    path={item.path}
    component={item.component}
    exact={item.exact}
  />
))

注意:如果你不需要自动生成路由,也可以用 routerData 自行处理。

2.1.2、菜单

菜单信息配置在 src/common/menu.js 中,它的作用是:

  • 配置菜单相关数据,菜单项的跳转链接为配置项及其所有父级配置 path 参数的拼接。
  • 为 src/common/router.js 提供路由名称(name)等数据,根据拼接好的跳转链接来匹配相关路由。

如果你的项目并不需要菜单,你也可以直接在 src/common/router.js 中配置 name 信息。

配置文件输出的菜单数据,可以直接提供给侧边栏组件使用。SiderMenu.js。除了生成菜单,菜单数据还可辅助生成重定向路由等模块,参考 BasicLayout.js#L154

2.1.3、面包屑

  之前提到的路由信息 routerData 可以直接传递给 PageHeader 组件用以生成面包屑,你可以用 props 或者 context 的方式进行传递。脚手架里的示例

2.2、需求示例

2.2.1、新增页面

  脚手架默认提供了两种布局模板:基础布局 - BasicLayout 以及 账户相关布局 - UserLayout,如上文提供的两种图片。

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

1》增加路由配置

// src/common/router.js
‘/dashboard/test‘: {
  component: dynamicWrapper(app, [‘monitor‘], () => import(‘../routes/Dashboard/Test‘)),
},

2》菜单配置

// src/common/menu.js
const menuData = [{
  name: ‘dashboard‘,
  icon: ‘dashboard‘,  // https://demo.com/icon.png or <Icon type="dashboard" />
  path: ‘dashboard‘,
  children: [{
    name: ‘分析页‘,
    path: ‘analysis‘,
  }, {
    name: ‘监控页‘,
    path: ‘monitor‘,
  }, {
    name: ‘工作台‘,
    path: ‘workplace‘,
  }, {
    name: ‘测试页‘,
    path: ‘test‘,
  }],
}, {
  // 更多配置
}];

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

2.2.2、新增布局模板

  如果提供的布局不能满足你的要求,就需要自己新建 Layout 模板了。假设有两个新的页面需要使用新模板,你需要先配置好路由及菜单:

1》路由设置

// src/common/router.js
‘/new‘: {
  component: dynamicWrapper(app, [‘monitor‘], () => import(‘../layouts/NewLayout‘)),
},
‘/new/page1‘: {
  component: dynamicWrapper(app, [‘monitor‘], () => import(‘../routes/New/Page1‘)),
},
‘/new/page2‘: {
  component: dynamicWrapper(app, [‘monitor‘], () => import(‘../routes/New/Page2‘)),
},

2》菜单设置

// src/common/menu.js
const menuData = [{
  name: ‘新布局‘,
  icon: ‘table‘,
  path: ‘new‘,
  children: [{
    name: ‘页面一‘,
    path: ‘page1‘,
  }, {
    name: ‘页面二‘,
    path: ‘page2‘,
  }],
}, {
  // 更多配置
}];

在根路由中增加这组新模板:

// src/router.js
<Router history={history}>
  <Switch>
    <Route path="/new" render={props => <NewLayout {...props} />} />
    <Route path="/user" render={props => <UserLayout {...props} />} />
    <Route path="/" render={props => <BasicLayout {...props} />} />
  </Switch>
</Router>

然后在你的新模板中,仿照 src/layouts/BasicLayout.js 或 src/layouts/UserLayout.js 生成路由列表即可。

2.3、带参数的路由/菜单

脚手架默认支持带参数的路由、菜单及面包屑配置,直接在路由的 key 以及菜单中的 path 配置即可:

1》路由

// src/common/router.js
‘/dashboard/:workplace‘: {
  component: dynamicWrapper(app, [‘chart‘], () => import(‘../routes/Dashboard/Workplace‘)),
},
‘/:list/table-list‘: {
  component: dynamicWrapper(app, [‘rule‘], () => import(‘../routes/List/TableList‘)),
},

2》菜单

// src/common/menu.js
const menuData = [{
  name: ‘dashboard‘,
  icon: ‘dashboard‘,
  path: ‘dashboard‘,
  children: [{
    name: ‘分析页‘,
    path: ‘analysis‘,
  }, {
    name: ‘监控页‘,
    path: ‘monitor‘,
  }, {
    name: ‘工作台‘,
    path: ‘:workplace‘,
  }],
}, {
  name: ‘列表页‘,
  icon: ‘table‘,
  path: ‘:list‘,
  children: [],
}, {
  // 更多配置
}];

2.4、嵌套布局

  有时在当前 layout 下还需要嵌套其他布局,例如有几个页面都需要展示同一个模块,你可以把这部分提炼出来变成一个新的布局,再到该布局下生成路由列表。与新增布局模板 的区别,只是不需要将它增加到根路由中。具体可以参照 src/common/router.js /list/search 相关配置,及相关组件文件。

2.5、嵌套路由同级展示

  脚手架默认使用工具函数 getRoutes 对 routerData 进行处理,然后生成路由列表,根据基本算法,在每一级组件中只会渲染当前 match.path 下最邻近的路由,所以,如果你要实现嵌套路由的同级展示(如:将 /list/search 和 /list/search/projects 在同一个地方渲染),就需要手动获取该路由的数据并添加在合适的地方。

{/* src/layouts/BasicLayout.js 类比你的上层 layout 组件 */}
<Content style={{ margin: ‘24px 24px 0‘, height: ‘100%‘ }}>
  <div style={{ minHeight: ‘calc(100vh - 260px)‘ }}>
    <Switch>
      {/* 默认生成的路由列表,不包含 /list/search/projects */}
      {
        getRoutes(match.path, routerData).map(item => (
          <Route
            key={item.key}
            path={item.path}
            component={item.component}
            exact={item.exact}
          />
        ))
      }
      {/* 补充 /list/search/projects 的路由 */}
      <Route exact path="/list/search/projects" component={routerData[‘/list/search/projects‘].component} />
      <Redirect exact from="/" to="/dashboard/analysis" />
      <Route render={NotFound} />
    </Switch>
  </div>
</Content>

同时在嵌套 layout 的文件中去掉这一条路由(如果还有下层路由需要 render)。

{/* src/routes/List/List.js 类比你的嵌套 layout 组件 */}
<Switch>
  {
    getRoutes(match.path, routerData).filter(item => item.path !== ‘/list/search/projects‘).map(item =>
      (
        <Route
          key={item.key}
          path={item.path}
          component={item.component}
          exact={item.exact}
        />
      )
    )
  }
</Switch>

2.6、隐藏菜单

如果需要隐藏某条菜单项,可以在该条数据中增加 hideInMenu 参数。

hideInMenu: true,  // 隐藏该条,或隐藏该组

2.7、隐藏面包屑

如需隐藏面包屑中的某个层级,可以增加 hideInBreadcrumb 属性。

// src/common/router.js
‘/dashboard/analysis‘: {
  component: dynamicWrapper(app, [‘chart‘], () => import(‘../routes/Dashboard/Analysis‘)),
  hideInBreadcrumb: true,  // 隐藏该条
},
‘/dashboard/monitor‘: {
  component: dynamicWrapper(app, [‘monitor‘], () => import(‘../routes/Dashboard/Monitor‘)),
},

2.8、关于 dynamicWrapper

import dynamic from ‘dva/dynamic‘;

// wrapper of dynamic
const dynamicWrapper = (app, models, component) => dynamic({
  app,
  // eslint-disable-next-line no-underscore-dangle
  models: () => models.filter(m => !app._models.some(({ namespace }) => namespace === m)).map(m => import(`../models/${m}.js`)),
  // add routerData prop
  component: () => {
    const routerData = getRouterData(app);
    return component().then((raw) => {
      const Component = raw.default || raw;
      return props => <Component {...props} routerData={routerData} />;
    });
  },
});import dynamic from ‘dva/dynamic‘;

// wrapper of dynamic
const dynamicWrapper = (app, models, component) => dynamic({
  app,
  // eslint-disable-next-line no-underscore-dangle
  models: () => models.filter(m => !app._models.some(({ namespace }) => namespace === m)).map(m => import(`../models/${m}.js`)),
  // add routerData prop
  component: () => {
    const routerData = getRouterData(app);
    return component().then((raw) => {
      const Component = raw.default || raw;
      return props => <Component {...props} routerData={routerData} />;
    });
  },
});

为了代码的简洁性,我们对 dva/dynamic 进行了二次封装,需要注意的是这里使用了 Webpack Code Splitting 的动态 importdva 的 dynamic 方法已经帮我们封装好了 Promise 动态加载的相关事宜,所以我们只需要直接使用即可。

原文地址:https://www.cnblogs.com/bjlhx/p/8973944.html

时间: 2024-08-30 15:39:29

003-ant design pro 路由和菜单的相关文章

Ant Design Pro路由菜单

config /config.js配置list路由指向页面../layouts/NewPage import defaultSettings from './defaultSettings'; // https://umijs.org/config/ import slash from 'slash2'; import webpackPlugin from './plugin.config'; const { pwa, primaryColor } = defaultSettings; // p

SpringBoot整合Ant Design Pro进行部署

一.Ant Design Pro 打包 1.1 运行 build打包 $ npm run build 1.2 将打包生成的静态文件拷贝到spring boot 项目中 构建打包成功之后,会在根目录生成 dist 文件夹,然后将dist 文件夹里的的文件复制到 spring boot 项目的 /src/main/resources/static 目录下 二.配置spring boot 项目可访问到static目录下的index.html 2.1 以gradle为例导入spring-boot-sta

ant design pro (十二)advanced UI 测试

一.概述 原文地址:https://pro.ant.design/docs/ui-test-cn UI 测试是项目研发流程中的重要一环,有效的测试用例可以梳理业务需求,保证研发的质量和进度,让工程师可以放心的重构代码和新增功能. Ant Design Pro 封装了一套简洁易用的 React 单元测试和 E2E 测试方案,在项目根目录运行以下命令就能运行测试用例. npm run test:all # 执行所有测试 二.详细 2.1.单元测试 单元测试用于测试 React UI 组件的表现.我们

ant design pro (十四)advanced 使用 CLI 工具

一.概述 原文地址:https://pro.ant.design/docs/cli-cn 为了更好以及高效的开发效率,我们提供了配套的 ant-design-pro-cli 工具. pro cli 提供了如下功能: pro new 新建一个脚手架,会自动将最新的 Ant Design Pro 脚手架下载到本地并安装 pro generate 新建一个模板,包含 model.service.page.component 二.使用过程 2.1.如何使用 使用 npm 安装到本地 npm instal

Ant Design Pro 中的服务端交互

前端请求流程 在 Ant Design Pro 中,一个完整的前端 UI 交互到服务端处理流程是这样的: UI 组件交互操作: 调用 model 的 effect: 调用统一管理的 service 请求函数: 使用封装的 request.js 发送请求: 获取服务端返回: 然后调用 reducer 改变 state: 更新 model 统一的请求处理都放在 services 文件夹中,并且一般按照 model 维度进行拆分文件 services/ user.js api.js ... 其中,ut

Nginx 部署 Ant Design pro

利用Ant Design pro开发的项目,如何用Nginx部署呢? 第一步:把项目打包,打包命令如下: npm run build 运行完毕会在项目目录下生成dist文件夹. 第二步:想要测试打包好的代码是否可以正常运行,安装serve,如下命令 npm i serve -g serve安装完毕,利用serve运行打包好的代码,运行命令: serve dist 测试完毕,代码可以正常运行. 第三步:用Nginx进行部署. 1.下载Nginx:http://nginx.org/en/downlo

如何创建Pull Request,以开源项目ant design pro为例

声明:本文章也是我本人参考网络上的一些教程写的,毕竟我也是第一次为开源项目做贡献,心里难免有点小激动.所以用此文章来记录这个过程,和一些操作方式.同时留作以后可供参考. 背景:最近做了公司一个项目,具体项目我也就不说了,反正用了React+Umi+Ant Design Pro.具体情况是这样,使用官方的SettingDrawer实现了在线切换主题的功能,但是官方的控件中会有如下拷贝设置按钮一直显示. 然而我想要的效果如右图 可是我的项目上线后,不需要复制主题配置进行分享,仅开发过程中设置默认主题

实战 ant design pro 中的坑

1.前戏: 1,替换mock数据: 1.将:.roadhogrc.mock.js 中的代理模式替换 当不使用代理的时候就会将所有 /api/*的链接换成 http://localhost:8080/ export default noProxy ? {'GET /api/*':'http://localhost:8080/'} : delay(proxy, 1000); 2.启动: window:npm run start:no-proxy 其他系统没试 坑 1. what?这是什么鬼没设置ke

使用React+Umi+Ant Design Pro实现生产环境动态切换主题,支持暗黑主题

投入前端开发也有1年的时间了,我还是很菜.在开发中还是很多技巧以及经验不够,写文章也是文笔不行,不过好在写的内容意思大概都能看懂.这次就来介绍一下我在开发过程中遇到的一些问题以及处理技巧. 两月前刚开始试用umi这个React的框架,使用AntD Pro创建好项目后,着实熟悉了几天,不过熟悉这个框架后,就觉得阿里的大佬还是牛.佩服. 事情是这样的,我们能够在AndD Pro的在线预览上看到能够动态切换主题.而实际拉下来的模板中却没有这个功能.我就开始了对比源码. 算了,先上一下项目目录结构吧,不