【避坑指“难”】react+umi权限控制一网打尽(路由权限and按钮权限)

1,544 阅读2分钟

权限控制是业务中最最最最最常见的,通常B端需要对不同的用户配置不同的权限,相应的按钮也仅开放给部分用户可见,下面是权限控制的实现方式。

一、菜单权限及路由权限

1、config/routes.tsx

添加access权限控制标识

{
    path: '/userCenter',
    name: '个人中心',
    access: 'userCenter',
    icon: 'GroupOutlined',
    hideInMenu: true,
    routes: [
      {
        access: 'userCenter',
        path: '/userCenter',
        component: './userCenter',
      },
      {
        name: '新建用户',
        access: 'userManageAdd',
        path: '/userCenter/userManage/create',
        component: './userCenter/UserManage/user/create',
      },
      {
        name: '修改用户',
        access:'userManageUpdate',
        path: '/userCenter/userManage/:id',
        component: './userCenter/UserManage/user/[id]',
      },
      {
        name: '角色管理',
        access:'userRoleAuth',
        path: '/userCenter/roleManage/auth',
        component: './userCenter/RoleManage/auth',
      },
    ],
  },

2、access.tsx

配置权限列表

export default function access(initialState: any) {
  const { menuItem } = initialState;
  return {
    //个人中心权限
    userCenter: menuItem.includes('4'),
    userInfo: menuItem.includes('5'),
    userInfoPsw: menuItem.includes('1015'),
    userManage: menuItem.includes('6'),
    userManageAdd: menuItem.includes('1016'),
    userManageUpdate: menuItem.includes('1017'),
    userManageDelete: menuItem.includes('1018'),
    userManagePsw: menuItem.includes('1020'),
    userRole: menuItem.includes('7'),
    userRoleAuth: menuItem.includes('1019'),
  };
}

项目启动时,routes.tsx 会自动根据 access.tsx 进行匹配,如果匹配到了权限,即可访问。

3、access.tsx中关于initialState.menuItem

在用户登录时,根据接口返回拿到所拥有的权限列表,储存在initialState.menuItem中,其中包含所有菜单的key值。

app.tsx


export async function getInitialState(): InitialState {
  const PermissionList = localStorage.getItem("rolePermissionList")?JSON.parse(localStorage.getItem("rolePermissionList")||''):''

  function lookForAllId(data = [], arr = []) {
    for (let item of data) {
        arr.push(item.key)
        if (item.children && item.children.length) 
        	lookForAllId(item.children, arr)
    }
    return arr
  }
  console.log('所有权限的key值',lookForAllId(PermissionList));

  const initState = {
    settings: {},
    menuItem: lookForAllId(PermissionList) || [],
  };

  return initState;
}

权限列表是children的树形结构,结构如下,所以需要遍历拿到所有的key值,代码中lookForAllId方法实现此步骤:

 {
    title: '0-0',
    key: '0-0',
    children: [
      {
        title: '0-0-0',
        key: '0-0-0',
        children: [
          { title: '0-0-0-0', key: '0-0-0-0' },
          { title: '0-0-0-1', key: '0-0-0-1' },
          { title: '0-0-0-2', key: '0-0-0-2' },
        ],
      },
      {
        title: '0-0-1',
        key: '0-0-1',
        children: [
          { title: '0-0-1-0', key: '0-0-1-0' },
          { title: '0-0-1-1', key: '0-0-1-1' },
          { title: '0-0-1-2', key: '0-0-1-2' },
        ],
      },
      {
        title: '0-0-2',
        key: '0-0-2',
      },
    ],
  },

上面就实现了菜单、路由的权限控制。

二、按钮权限

1、页面中引入useAccess

import { useAccess } from 'umi';
const access = useAccess();

根据权限判断来实现组件的显示与隐藏:这里将在access.tsx中进行匹配,前面有相关配置

{access.userInfo ? (
    <TabPane tab="个人信息" key="userinfo">
        <UserInfo />
    </TabPane>
) : ''}
{access.userManage ? (
    <TabPane tab="个人用户管理" key="userManage">
        <UserInfo />
    </TabPane>
) : ''}