美文网首页
react antd后台管理系统路由、导航设计

react antd后台管理系统路由、导航设计

作者: 赖次Go | 来源:发表于2019-04-15 15:50 被阅读0次

    作为主流框架,本人比较喜欢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

    相关文章

      网友评论

          本文标题:react antd后台管理系统路由、导航设计

          本文链接:https://www.haomeiwen.com/subject/ioiwzftx.html