react 实现权限管理和页面动态渲染树形控件

react权限管理

后端数据返回示例

{
     
    code: 200,
    userInfo: {
     
        name: '李四',
        age: '22',
        sex: '男'
    },
    menuInfo: [
        {
     
            menuId: 0,
            menuName: "首页",
            menuUrl: "/home/table",
            pathname: "Dish",
            componentPath: "Table",
            menuImgClass: 'el-icon-dish',
            menuState: "0",
            menuChilds: []
        }, {
     
            menuId: 1,
            menuName: "菜品管理",
            menuUrl: "/home/Dish",
            pathname: "Dish",
            componentPath: "Dish",
            menuImgClass: 'el-icon-dish',
            menuState: "0",
            menuChilds: [{
     
                menuId: 9,
                menuName: "菜品设置",
                menuUrl: "/home/Dish/DishSetList",
                pathname: "DishSetList",
                componentPath: "DishSetList",
                menuImgClass: '',
                menuState: "0",
                menuChilds: []
            },
            ]
  }

登陆之后 将数据保存在mobx或者redux中,再通过session进行本地存储,将数据注入到index中,在需要的页面进行调用

使用之前,大家先去了解一下mobx和redux如何使用

我这里用的是mobx
状态管理器中:

import {
     observable, action} from 'mobx'

class userStore {
     
    @observable user = JSON.parse(sessionStorage.getItem('user'))||{
     }
    @observable menu = JSON.parse(sessionStorage.getItem('menu'))||{
     }
    @observable isLogin = false
    @observable token = ""

    @action
    login(user, token) {
     
        this.user = user;
        this.token = token;
        this.isLogin = true
        sessionStorage.setItem('user',JSON.stringify(user))
    }

    setMenu(menu) {
     
        sessionStorage.setItem('menu',JSON.stringify(menu))
        this.menu = menu;

    }

}

export default userStore

index.js入口文件中

index注入:
<Provider {
     ...store}>
    <App/>
</Provider>,

在菜单组件中进行调用,这里使用了迭代思想,通过判断其是否有子路由进行迭代处理,动态的生成菜单

import React from 'react'
import {
     Menu} from "antd";
import {
     Link} from "react-router-dom";
import {
     inject, observer} from "mobx-react";

const {
     SubMenu} = Menu;
//此处要引用mobx中的user
@inject('user')
@observer
class Nav extends React.Component {
     
    constructor(props) {
     
        super(props);
        this.state = {
     
            menuList: this.props.user.menu
        }
    }

    bindMenu(menulist) {
     
        let MenuList = menulist.map((item) => {
     
            if (item.menuState !== "1") {
     
                if (item.menuChilds.length === 0) {
     
                    return <Menu.Item key={
     item.menuId}>
                        <Link to={
     item.menuUrl}>{
     item.menuName}</Link>
                    </Menu.Item>
                } else {
     
                    return <SubMenu key={
     item.menuId} title={
     item.menuName}>
                        {
     this.bindMenu(item.menuChilds)}
                    </SubMenu>
                }
            }
        });
        return MenuList
    }

    render() {
     
        let list = this.bindMenu(this.state.menuList);
        return (
            <Menu
                mode="inline"
                style={
     {
     height: '100%', borderRight: 0}}
                theme="dark"
                multiple={
     false}
                className="menuList"
            >
                {
     list}
            </Menu>

        )
    }
}


export {
     Nav as default}

在路由组件中生成动态的路由,也是通过迭代的思想进行判断子路由,进行添加。这里会遇到一个问题。同级路由和子路由之间的生成,什么时候使用嵌套路由,什么时候直接使用同级路由。

import React from 'react'
import {
     Route, Switch} from 'react-router-dom'
import {
     inject, observer} from "mobx-react";
import loadable from '@loadable/component'

@inject('user')
@observer
class Routes extends React.Component {
     
    constructor(props) {
     
        super(props);
        this.state = {
     
            routeList: this.props.user.menu
        }
    }

    setRoute(menuList) {
     

        let RouteList = menuList.map((item) => {
     
            if (item.menuChilds.length === 0) {
     
                return <Route key={
     item.menuId} path={
     item.menuUrl}
                              component={
     loadable(() => import(`../pages/${
       item.componentPath}`))}/>
            } else {
     
                return [...this.setRoute(item.menuChilds), <Route key='00' path="/home" exact component={
     loadable(() => import('../pages/Index'))}></Route>]

        })
        return RouteList
    }

    render() {
     
        let Routes = this.setRoute(this.state.routeList)
        return (
            <Switch>
                {
     this.props.location.pathname !== "/login" && this.props.user.isLogin === false ?
                    window.location.href='/login' : Routes}
            </Switch>
        )
    }
}


export {
     Routes as default}

注:本文使用antd UI框架
动态绑定到页面的树形控件上去。

constructor() {
     
    super();
    this.state = {
     
        modalRightInfoVisible: false,//模态框弹出
        RoleHasRouter: []//需要动态绑定到树形控件上的路由id
    }
}
//处理拿到的当前角色的menuInfo
getRouterId(menuInfo) {
     
    let RouterId=[];
    for (let i = 0; i < menuInfo.length; i++) {
     
        if (menuInfo[i].menuState !== "1") {
     
            if (menuInfo[i].menuChilds.length === 0) {
     
                RouterId.push(menuInfo[i].menuId + '')
            } else {
     
               RouterId.push(menuInfo[i].menuId + '')
                this.getRouterId(menuInfo[i].menuChilds)
            }
        }
    }
    for (let i = 0; i < RouterId.length; i++) {
     
        if (RouterId[i].length > 2) {
     
            RouterId.splice(i, 1)
        }
    }
    return RouterId
}

//点击授权打开弹出框,实现动态绑定数据的函数
openModalRightInfo(id) {
     
    //这里是返回角色信息时已经返回对应权限,所以需要从数组中获取值
    let data = [];
    for (let i = 0; i < this.state.RoleList.length; i++) {
     
        if (id === this.state.RoleList[i].role_id) {
     
            data = this.state.RoleList[i].menuInfo
        }
    }
    this.setState({
     
        RoleHasRouter: this.getRouterId(data)
    })
    this.setState({
     modalRightInfoVisible: true});
}

//生成树形控件
SetRouter(RouterList) {
     
    let checkBox = RouterList.map((item) => {
     
        if (item.menuState !== "1") {
     
            if (item.menuChilds.length === 0) {
     
                return <TreeNode title={
     item.menuName} key={
     item.menuId} checkable/>
            } else {
     
                return <TreeNode
                    title={
     item.menuName}
                    key={
     item.menuId}
                >
                    {
     this.SetRouter(item.menuChilds)}
                </TreeNode>
            }
        }
    })
    checkBox = checkBox.filter(function (val) {
     
        return !(!val || val === "");
    })
    return checkBox
}
//树形控件选中状态发生改变
onRouterSelectData = (checkedKeys) => {
     
    this.setState({
     
        RoleHasRouter:checkedKeys
    })
    // this.state.RoleHasRouter = checkedKeys
}
//授权弹出框
<Modal title="授权"
       visible={
     this.state.modalRightInfoVisible}
       cancelText='取消'
       okText='修改'
       onCancel={
     () => {
     
           this.setState({
     
               modalRightInfoVisible: false,
               RoleHasRouter:[]
           })
       }}
       onOk={
     () => {
     
           this.setRouterRight()
       }}
>
    <div className='checkBox'>
        <Tree
            checkable
            onCheck={
     this.onRouterSelectData.bind(this)}
            checkedKeys={
     this.state.RoleHasRouter}
        >
            {
     this.SetRouter(this.state.RouterList)}
        </Tree>
    </div>
</Modal>

你可能感兴趣的:(reactjs)