react后台管理配置路由及侧边栏:

react后台管理系统路由配置:

大概需求:

假设dashboard文件放的是整个页面,分为导航,和侧边栏,中间内容栏;导航和侧边每个路由都需要,将相关的路由页面都放到中间内容共栏就可以。

1、分为两部分大文件login登入页面/ 转到到dashboard,
这样分的好处是,不用跳转到一个页面就判断有没有登入。这里进行统一判断,如果没有登入 ,其他以/ 开头的页面都会跳转到login中。
一旦登入后就跳转到dashboard页面中,这个页面有导航栏,和侧边栏,这两个是公用内容,哪里都用的上。下面部分就是动态会变的。

一、文件:router.js路由配置

做判断,登入了就允许看所有页面,没有登入就打到登入页面

import React, { Component } from 'react' //引入核心
import { //引入路由相关配置
    HashRouter,  // 构建 hash 路由, #/home #/login  === ( Vue mode:hash )
    // BrowserRouter,// 构建 history 路由  /home /login === ( Vue mode:history )
    Redirect, //重定向
    Route, //路由坑
    Switch //模糊匹配,箱单与Switch判断语句
} from 'react-router-dom'
//-------blog 自定义组件-------------------------
import Login from '../views/login/Login' //111、登入页面
import DashBoard from '../views/dashboard/DashBoard'//222、设置为/ 的页面,整个页面结构都在这个文件,名字随便取

export default class Router extends Component {
    render() {
        return (
            <HashRouter> //哈希路由
              <Switch> //判断路由,先匹配登入页面,匹配上就brack出去
                <Route path="/login" component={Login}/>
                 路由拦截--三目 ————用render箭头函数形式,做判断,是否有token,有就说明登入,能进入到后台页面,没有就打回登入页面
                <Route path="/" render={()=>
                    localStorage.getItem("token")?<DashBoard/>:<Redirect to="/login"/>
                } />
              </Switch> 
            </HashRouter>
                )
            }
        }
2、配置完成后就直接在App.js中引入,让他加载这个路由页面就可以了

文件:App.js配置使用

import React from 'react'; //引入核心react
import BlogRouter from './router' //引入router路由配置文件
//根组件
class App extends React.Component{
  render(){
    return <BlogRouter/> //直接return出去,变成jsx文件供页面使用
  }
}

export default App;
3、 dashboard文件用于配置整个页面结构及路由:( 斜杠 / 页面 )

真实工作中权限这里不用自己做判断,我们只负责循环操作

//引入相关的路由及核心
import React, { Component } from 'react'
import { Route, Redirect, Switch } from 'react-router-dom'
import Home from '../home/Home'
import Users from '../usermanage/Users'
import SideMenu from './SideMenu' //组件的侧边栏,用antd-UI搭建
import TopHeader from './TopHeader' //组件的导航栏,用antd-UI搭建
import './index.css'

//antd组件库的配置
import { Layout } from 'antd';
import Create from '../article-manage/Create'
const { Content } = Layout; //解构

export default class DashBoard extends Component {
    render() {
        let { roleType } = JSON.parse(localStorage.getItem("token")) //将token结构出来
        return (
            <Layout>
                {/* 自定义的sidemenu */}
                <SideMenu></SideMenu> //侧边栏
                <Layout className="site-layout"> 
                    <TopHeader></TopHeader> //组件导航栏
                    <Content //以下全是组件内容区的配置,
                        className="site-layout-background"
                        style={{
                            margin: '24px 16px',
                            padding: 24,
                            minHeight: 'auto',
                        }}
                    >
                        <Switch> //开始相关的路由配置
                            {/* home路由 */}
                            <Route path="/home" component={Home} />
                            {/* 用户权限-用户列表 */} //这个判断是根据token的内容,判断登入后用户的权限,如果登入用户权限大于3的话就渲染这个路由组件,如小于,就不渲染,这个用户就没有权限看着列表
                            {roleType >= 3 ?
                                <Route path="/user-manage/users" component={Users} />
                                :
                                null
                            }

                            {/* 权限管理-权限列表,角色列表 */}
                            {
                                roleType >= 3 ?
                                    <Route path="/right-manage" component={Manage} />
                                    : null
                            }
                            {/* 文章管理- 文章列表 文章分类 */}
                            <Route path="/article-manage/list" component={List} />
                            <Route path="/article-manage/preview/:myid" component={Preview} exact /> //动态组件的详情页面
                            <Route path="/article-manage/create" component={Create}/>
                            <Redirect from="/" to="/home" exact /> //重定向到home页面
                            <Route path="*" component={NotFound} /> //上面的都匹配不到,设置 “ * ”后随便在地址栏乱输都会匹配404组件
                        </Switch>
                    </Content>
                </Layout>
            </Layout>
        )
    }
}
渲染路由的第二种情况:(后端返回的数据直接渲染)
import React, { Component } from 'react' //引入核心
import {Route,Redirect,Switch} from 'react-router-dom'//引入路由
import newList from '@/views/index' //引入后端数据
import { Layout } from 'antd' //antd
const { Content } = Layout;//antd
export default class Contents extends Component { //组件
    constructor(props) {
        super(props)
        this.state = {
        }
    }
    forList = (newList) =>{ //定义函数,接收后端数据
        // console.log(newList)
      return newList.map((item) =>{ //循环
           if(item.children) { //判断是否有孩子,有就继续循环
            return item.children.map((item) =>{ //循环孩子数据路由
              return <Route exact key={item.id} path={item.path} component={item.component}></Route>
               })
           }else{//如果没有孩子就直接循环
            return <Route exact key={item.id} path={item.path} component={item.component}></Route>
           }
        })
    }
    render () {
        return (
            <Content
                className="site-layout-background"
                style={{
                    margin: '24px 16px',
                    padding: 24,
                    minHeight: '100%',
                }}
            >
               <Switch>//保留模糊匹配
               {this.forList(newList)} //调用上面定义的函数,将后端数据传递过去用于渲染路由
               <Redirect from="/*" to="/home"></Redirect> //路由重定向
               </Switch> 
                {/* Content */}
            </Content>
        )
    }
}

二、侧边栏配置:(路由跳转)

1、先配置假数据用于做侧边栏的循环:(工作中是后端返回

list.js文件:
const MyData = [
    {//一级菜单需要的参数
        title:"首页",
        icon:UserOutlined, 
        permission:1, //权限判断
        path:'/home' //设置的好处:1、可以用来跳转页面,2、可以用来配置下拉菜单的默认下来项
    },
    {
        title:"用户管理",
        icon:VideoCameraOutlined,
        permission:3,
        path:'/user-manage',
        children:[ //二级菜单的配置
            {
                title:"用户列表",
                 icon:UserDeleteOutlined ,
                 permission:3,
                 path:"/user-manage/users"
            }
        ]
    },
]
export default MyData //抛出去

配置侧边栏:
用antd-UI框架布局侧边栏
defaultSelectedKeys:组件库提供设置菜单高亮的属性
defaultOpenKeys:组件库提供设置菜单默认展开效果,key需要和后端返回的数据路径一致
注:递归调用时经典

import React, { Component } from 'react' //引入react核心
import MenuArr from '../../router/list.js'//引入上面定义的假数据
import { Layout, Menu } from 'antd';
import { withRouter } from 'react-router'; //引入高阶组件
import {connect} from 'react-redux' //引入react-redux

const { Sider } = Layout; //解构
const { SubMenu } = Menu;

class SideMenu extends Component { //组件
    state = {
        collapsed: false
    }
    //1、自己封装渲染函数,遍历侧边栏
    renderMenu = (menus)=>{ //BBB
       let {roleType} = JSON.parse(localStorage.getItem("token"))
       //2、roleType 当前登录用户的roleType(就是用户权限,从token中拿出来做判断,权限越高看的越多
       return menus.map(item=>{
           //3、提示:判断当前登录的用户的角色值(roleType),跟当前要渲染的侧边栏项需要的角色值进行对比
            if(item.children && roleType >= item.permission){ //4、判断是否有孩子参数,有就渲染二级标题,并且判断登入用户的权限是不是大于标题数据的权限,大于就渲染,小于就隐藏(就是数据中定义的permission)
                return <SubMenu key={item.path} title={ //重:将每个渲染的标题都设置key(就是数据中定义的path="/home")用于做编程试导航和菜单高亮
                    <span>
                        <item.icon/>
                        <span>{item.title}</span>
                    </span>
                }>
                    {
                        //递归用法
                        this.renderMenu(item.children) //重:7、下面还有children在继续递归渲染,(就不需要每次都去做循环渲染)
                    }
                </SubMenu>    
            }else{
                if( item.permission > roleType){ //6、判断登入的权限是否大于当前标题数据的权限,大于就显示,小于就隐藏。
                    return null
                }
                return ( //5、如果没有children孩子数据,就直接渲染一级标题,menu
                    <Menu.Item key={item.path} icon={<item.icon />}>重:将每个渲染的标题都设置key(就是数据中定义的path="/home")用于做编程试导航和菜单高亮
                            {item.title}
                    </Menu.Item>
                )
            }
        })
    }

    handleChangePage = (obj)=>{  //AAA
        // console.log(obj)
        // 高阶组件提供
        this.props.history.push(obj.key)//key路由对应的路径,进行点击每一个标题的时候,条状到响应的路由去
    }
    render() {
        // console.log(this.props) //拿到此时路径
        let selectedKey = this.props.location.pathname  //设置defaultSelectedKeys
        let openKey = "/"+this.props.location.pathname.split("/")[1] //截取二级路由的一级路径,设置defaultOpenKeys
        return (
            <Sider trigger={null} collapsible collapsed={this.props.isCollapsed}>
                {/* <div className="logo" /> */}
                {
                    /*
                        andt组件库提供:defaultSelectedKeys :高亮显示谁?//从编程试导航中结构出来path来,给到这个属性
                                       defaultOpenKeys://初始展开的 SubMenu 菜单项 key 数组 (前提是渲染标题的时候,key要和解构出来的path相对应,不然初始化展开不起作用)  
                    */
                }
                <Menu theme="dark" mode="inline" defaultSelectedKeys={[selectedKey]} defaultOpenKeys={[openKey]}
                    onClick ={this.handleChangePage} //AAA
                    //点击 MenuItem 调用此函数,会传递点击的是具体的哪一个值过去,就包含数据的path
                >
                    { //BBBB
                        this.renderMenu(MenuArr) //调用上面抽离的函数,渲染侧边栏,传递的值就是引入的假数据
                    }
                </Menu>
            </Sider>
        )
    }
}
// connec拿到了store, store.getState()
const mapStateToProps = state => {
    // console.log(state)
    return {
        name:"kerwin",
        a:1,
        isCollapsed:state.isCollapsed
    } //函数返回值 ,就是将来往sideMeun 组件传来的属性
}// 映射redux 状态==>当前组件属性


export default connect(mapStateToProps)(withRouter(SideMenu))
  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值