作为主流框架,本人比较喜欢react风格,引入导入可能多些代码,相比Vue更为完整
选择antd作为web后台管理系统框架,其一是ant的UI好看,其二组件完善
不论是新手还是老手都比较愿意去使用ant,彩蛋事件忽略
本文主要是讲react框架上后台管理系统路由设计,ant并非项目必须
主要使用react-router-dom 4.0模块,
- 实现一套路由配置同时兼容路由和导航条的渲染,其中借鉴了Vue Router的config的写法
- 实现登录验证
- 用户管理权限部分
/* 使用Mobx作为状态管理 */
作为本人设计笔记,也供在线点评
嵌套路由
例:
这里有一个后台管理系统,通常这套系统会有主页、用户管理两个页面,用户管理里面会有用户详情,修改编辑这类
那么我们会定义用户管理页面的path:/user,用户详情/user/detail,单个用户的情况下/user/detail/:id,这样的写法。
当我们用户详情下面再有什么单独页面显示,那么就会出现/user/detail/:id/**这类,那么这种就需要嵌套路由
使用react-router-dom完成嵌套路由,具体写法
<Switch>
<Route path="/index" />
<Route path="/user">
<Switch>
<Route path="/user/detail/:id" component={ /*子路由组件 */ }></Route>
/* 希望路由只针对某个用户,而非针对用户的访问情况,需要跳转到相应上级页面 */
<Route render={ () => <Redirect to="/user" /> } />
</Switch>
</Route>
</Switch>
以上即为路由的嵌套写法
导航部分:
image.png如这样,用户管理,下面有其他项,经过分析,路由与导航是可以统一配置的
那么为了统一,方便配置(少量代码,做更多有趣的事),我们会定义一个json,同时去处理路由与nav
简单定义一个RouterConfig.js文件,
export default [
{
path : '/home', // 一级路由path
meta : '主页', // 导航名称
icon : '', // 所用icon
role : [], // 适用权限
// 所用组件
component : sync(() => import( /* webpackChunkName: 'home' */ '@/Pages/Home/index.js')),
children : [ //二级路由
{
path : '/one', //二级路由path ,react将会渲染为/home/one
meta : '嵌套1',
icon : '',
role : [],
component : sync(() => import ( /* webpackChunkName: 'home_page_one' */ '@/Pages/Home/one')),
children : []
},
{
path : '/two',
meta : '嵌套2',
icon : '',
role : [],
component : sync(() => import ( /* webpackChunkName: 'home_page_one' */ '@/Pages/Home/two')),
children : [],
},
],
},
{
path : '/user',
meta : '用户',
icon : '',
role : [],
component : sync(() => import( /* webpackChunkName: 'user' */ '@/Pages/User/index.js')),
children : [
{
path : '/one',
meta : '嵌套1',
icon : '',
role : [],
component : sync(() => import ( /* webpackChunkName: 'user_page_one' */ '@/Pages/User/one')),
children : [],
},
{
path : '/two',
meta : '嵌套2',
icon : '',
role : [],
component : sync(() => import ( /* webpackChunkName: 'user_page_two' */ '@/Pages/User/two')),
children : [],
},
]
}
]
是不是更像是一个Vue Router 配置呢
直面React-router-dom 路由全部配置
import RouterConfig from 'RouterConfig.js'
class RouterComponent extends React.component {
render () {
return (
<Switch>
{
RouterConfig.map(
router => {
return (
<Route
path={ router.path }
key={ router.path }
component={
props => {
return (
<RouteComponent
router={ router }
{ ...props }
/>
)
}
}
/>
)
}
)
}
</Switch>
)
}
}
一级路由
export const RouteComponent = props => {
return (
<Switch>
{
props.router.children.map (
router => {
return (
<Route
path={ props.match.url + router.path }
key={ router.path }
{ ...props }
component={
npx => {
return (
<RouteChildrenComponent
router={ router }
{ ...npx }
/>
)
}
}
/>
)
}
)
}
{
<Route
component={
() => {
return <Container { ...props } component={ props.router.component } />
}
}
/>
}
</Switch>
)
}
子路由
export const RouteChildrenComponent = props => {
return (
<Switch>
{
props.router.children.map(
npx => {
return (
<Route
path={ npx.path ? props.match.url + npx.path : '' }
key={ npx.meta }
component={
props => {
return (
<Container { ...props } component={ npx.component } />
)
}
}
/>
)
}
)
}
{
props.router.component ?
(
<Route
render={
() => {
return (
<Container { ...props } component={ props.router.component } />
)
}
}
/>
)
: <Route render={ () => <Redirect to='/login' /> } />
}
</Switch>
)
}
渲染导航
class MenuComponent extends React.Component {
render () {
let collapsed = this.props.store.collapsed
let store = this.props.store;
const defaultOpenKeys = router.map( item => item.path )
return (
<Menu
defaultSelectedKeys={ [ this.props.location.pathname ] }
theme="dark"
defaultOpenKeys={ defaultOpenKeys }
mode="inline"
inlineCollapsed={ collapsed }
>
{
router.map(
npx => {
return (
<SubMenu
key={ npx.path }
title={
<span>
<Icon type={ npx.icon ? npx.icon : 'user' } />
<span>{ npx.meta }</span>
</span>
}
>
{
/*这里并未做权限验证,只是做了个基本的应用*/
npx.role === '' || store[npx.role] ?
<MenuItem
key={ npx.path }
onClick = {
() => this.props.history.push( npx.path )
}
>
{ npx.meta }
</MenuItem> : ''
}
{
npx.children.map(
item => {
/*这里并未做权限验证,只是做了个基本的应用*/
return (
store[ item.role ] || item.role === '' ? (
<Menu.Item
key={ npx.path + item.path }
onClick={
() => this.props.history.push( npx.path + item.path )
}
>
{ item.meta }
</Menu.Item>
) : ''
)
}
)
}
</SubMenu>
)
}
)
}
</Menu>
)
}
}
一个Vue 路由配置拿到React的小例子,写好配置就是做好渲染就可以啦,so,是需要去看代码的。
git:
https://github.com/wulibaibao/react-antd-demo
个人博客:
https://www.wulibaibao.com
网友评论