3.1 页面布局Flex与Grid
3.2 React-router路由
React-router路由需要使用6.0的版本yarn add react-router@6 react-router-dom@6
。需要解决的问题是动态路由和组件动态加载。
3.2.1 服务器端返回数据
"user":{
username: "admin",
token: "123456",
menus: [{id: "menu-1",
name: '用户管理',
url: '/users',
component: './user'
},
{
id: "menu-3",
name: "数据管理",
children: [{
id: "menu-3-1",
name: '地区数据',
url: '/region',
component: './region'
},
{
id: "menu-3-2",
name: '行政单位数据',
url: '/executive',
component: './executive'
},
]
}
]
}
3.2.2 动态菜单生成
// 菜单递归函数
const getMenuNode=(menus:Array<HomeMenuItem>)=>{
return menus.map((menu:HomeMenuItem)=>{
if(!menu.children){
return(
<Menu.Item key={menu.id} style={{margin:0}}>
<Link key={menu.id} to={menu.url}>{menu.name}</Link>
</Menu.Item>
)
}else{
return(
<SubMenu key={menu.id} title={menu.name}>
{
getMenuNode(menu.children)
}
</SubMenu>
)
}
})
}
{/* Antd组件 */}
<Sider collapsible collapsed={collapsed} onCollapse={()=>setCollapsed(!collapsed)}>
<Menu mode='inline'>
{getMenuNode(menus)}
</Menu>
</Sider>
3.2.3 路由组件动态加载
点击react-router路由的Link会加载Route标签的组件,这个组件需要动态加载,根据react-router的官方推荐使用loadable-components
(https://loadable-components.com/)组件动态加载,yarn add @loadable/component
,因为使用Typescript因此需要添加类型支持 yarn add @types/loadable__component -D
。
//组件根据菜单描述动态加载
const getPageComponent = (menus:Array<HomeMenuItem>)=>{
let array:Array<any>= new Array<any>()
for(let i=0;i<menus.length;i++){
if(!menus[i].children){
let T1 = loadable(()=>import(`${menus[i].component}`))
//react-router v6版本需要user/*这样的url来匹配子路由
let p = menus[i].url+"/*"
array.push(<Route key={menus[i].id} path={p} element={<T1/>}/>);
}else{
for(let j= 0;j<menus[i].children!.length;j++){
let T1 = loadable(()=>import(`${menus[i].children![j].component}`))
//react-router v6版本需要user/*这样的url来匹配子路由
let p = menus[i].children![j].url+"/*"
array.push(<Route key={menus[i].children![j].id} path={menus[i].children![j].url} element={<T1/>}/>);
}
}
}
return array
}
//react-router v6 版本使用方法
<Routes>
<Route path="/" element={<HomeContentPage />}/>
{getPageComponent(menus)}
{/*
<Route path="/region" element={<RegionPage />}/>
<Route path="/executive" element={<ExecutivePage />}/> */}
</Routes>