antd pro 动态菜单与动态路由
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了antd pro 动态菜单与动态路由相关的知识,希望对你有一定的参考价值。
参考技术A 项目中使用了动态菜单,其中含有固定和非固定的菜单,但是我们的后端同事只在登陆时返回含有动态菜单 name 的数组。阅读源码我们可以发现,在 layouts/BasicLayout 中可以看到 menuData 是从 menu.js 中获取的
routes 就是运行生成的 .umi/router.js 的内容,将其输出我们可以直观的看见它的具体结构
在 router.config.js 中使用 dynamic 去标志该目录(路由)是动态的
大体思路就是对 routes 进行数据处理,将登录获取到的特定路由(这里用 name 属性标识)在 routes 中过滤出来
此时的 menuData 就是我们想要的实际菜单了
旧版本(2.x)回到 layouts/BasicLayout 中,从props中取出 routerMap
权限组件 Authorized ,使用这个组件就能实现不跳转的 404、403页面了
但是3.x的写法会导致出现404或者403时会全屏,所以如果是局部应用的话,可以将登录校验、404/403校验分离,将 Routes 分别挂在对应的路由层级上
ant-design-pro 动态菜单-路由详解
ant-design-pro 动态菜单-路由详解
最近利用ant-design-pro开发项目要实现之前的项目嵌入到新项目里来,并且根据和后台的接口返回的数据显示侧边栏菜单。既然是是利用别人的架构那当然是从文档中找实现的方法,终于不负苦心人在https://pro.ant.design/docs/router-and-nav-cn文档那里找到初步的解决方法
进入src/layouts/Basilayout.js在官网中直接复制该代码,将原文件替换。
现在正式进入正题。
1,在src/layouts/Basilayout.js中利用connect与拉取菜单的models建立联系
我的是放在views的models下面所以代码如下
export default connect((global, setting, views ) => (
collapsed: global.collapsed,
layout: setting.layout,
…setting,
…views,
))(BasicLayout);
2,在src/layouts/Basilayout.js中的生命周期函数componentDidMount里面调用拉取菜单的接口,
componentDidMount()
const dispatch = this.props;
dispatch(
type: ‘views/fetch’,
);
我调取的是下面views.js里面的effects的fetch方法
至于model里面怎么写可以看官方文档https://pro.ant.design/docs/server-cn
这里是我写的一个views的model —(下面代码的关键字是getMenuMapArrData )
import getMenuList from ‘@/services/api‘
import getMenuSessionData, getMenuMapArrData from ‘@/utils/utils.js‘
export default
namespace: ‘views‘,
state:
datas: [],
urlValues: ‘https://boss.icarbonx.com/lims-ui/baselab/qcPaths/exception‘,
urlDatas: [],
,
effects:
*fetch( payload , call, put )
const response = yield call(getMenuList, payload);
console.log(response,‘得到列表‘)
yield put(
type: ‘save‘,
payload: response
)
,
*changeurl( payload , call, put )
yield put(
type: ‘change‘,
payload: payload
)
,
,
reducers:
save(state, action)
return
...state,
datas: getMenuMapArrData(action.payload),
urlDatas: getMenuSessionData(action.payload),
,
change(state, action)
return
...state,
urlValues: action.payload,
,
3、getMenuList菜单接口返回的格式化,当然有些老铁直接就按照router.config.js的形式写的但是有些情况是后台人员返回的数据并不是这样这就需要我们格式化。
理想情况返回的数据是
[
path: ‘/user‘,
component: ‘../layouts/UserLayout‘,
routes: [
path: ‘/user‘, redirect: ‘/user/login‘ ,
path: ‘/user/login‘, component: ‘./User/Login‘ ,
path: ‘/user/register‘, component: ‘./User/Register‘ ,
path: ‘/user/register-result‘, component: ‘./User/RegisterResult‘ ,
],
]
**现实情况返回的:**
**[
"id": "dashboardws",
"name": "Dashboard",
"description": "Dashboard",
"url": ‘https://boss.xxx.com/qcScheme/qcPrograms‘,
component: ‘./View/home‘,
"children": []
,
"id": "knowledge",
"name": "Knowledge Platform",
component: ‘./View/home‘,
"url": null,
"children": [
"id": "gene",
"name": "Gene",
component: ‘./View/home‘,
"url": ‘https://XXX.XXX.com/qcPaths/qualityProjectQuery‘,
"children": null
,
"id": "phenotype",
"name": "Phenotype",
component: ‘./View/home‘,
"url": ‘https://XXX.XXX.com/lims-ui/baselab/qcPaths‘,
"children": null
,
"id": "microbes",
"name": "Microorganism",
component: ‘./View/home‘,
"url": ‘https://boss.xxx.com/qcPaths/qcSamplesCheck‘,
"children": null
]
,
"id": "indicatorww",
"name": "Index Platform",
"url": ‘https://baidu.com‘,
"children": []
,
"id": "report",
"name": "Report Platform",
"url": ‘https://boss.xxx.com/limb/qcScheme/qcSamples‘,
"children": []
]
这样的话不能直接用要先处理,我的话是通过utils.js里写一个名叫getMenuMapArrData的方法进行格式化将后台返回的数据处理成类似理想状态的格式,
类似于 —(下面代码的关键字是routes)
const menuListData = [
"id": "knowledge",
"name": "Knowledge Platform",
component: ‘./View/home‘,
"url": null,
"routes": [
"id": "gene",
"name": "Gene",
component: ‘./View/home‘,
"url": ‘https://XXX.XXX.com/qcPaths/qualityProjectQuery‘,
"children": null
,
"id": "phenotype",
"name": "Phenotype",
component: ‘./View/home‘,
"url": ‘https://XXX.XXX.com/lims-ui/baselab/qcPaths‘,
"children": null
,
"id": "microbes",
"name": "Microorganism",
component: ‘./View/home‘,
"url": ‘https://boss.xxx.com/qcPaths/qcSamplesCheck‘,
"children": null
]
,
]
主要是你格式化的这里里面要有routes这个属性,系统才能识别出你的菜单,当然没有子级菜单可以不需要改。
4、需要在router.config.js里面把你的菜单全集写出来。你动态拉取的必须是你router.config.js里面有的路由才能有效。
5、我那里是通过iframe嵌套一些页面所以我在写router.config.js的路由规则时我用到了动态路由的配置
即在router.config.js
path: ‘/:post’,
component: ‘./View/home’,
,
path: ‘/:post/:id’,
component: ‘./View/home’,
,
经过我的实验这个要写在
component: ‘404’,
,
的前面才不会被404 重定向
6、在src/layouts/Basilayout.js中获取处理后的菜单列表数据,在render()函数里面const menuData = this.getMenuData()这句,调取getMenuData方法,这里面通过this.props动态获取到datas,datas就是我处理后的菜单数据。
注意:如果原数据不是理想数据而又不处理,而是在这个getMenuData里处理,会发生一些意想不到的错误。
getMenuData()
const
datas,
route: routes ,
= this.props;
const newRoutes = [...datas, ...routes]
return memoizeOneFormatter(Array.from([...newRoutes]));
7、至此就结束了应该就可以完成了
以上是关于antd pro 动态菜单与动态路由的主要内容,如果未能解决你的问题,请参考以下文章