这是我写的简单的react的动态路由权限,我用的是dva仓库
第一步,创建,封装路由
import type { MenuProps } from "antd"
import { Iitems } from "../../ts/ts"
// type MenuItem = Required<MenuProps>['items'][number];
import BannerManage from "../bannerManage/bannerManage"
import ActivityManage from "../activityManage/activityManage"
import Register from "../userManage/register"
// import UserManage from '../userManage/userManage';
import admin from '../userManage/admin';
const items: Iitems[] = [
{
key: "/home/bannerManage",
label: "轮播图管理器",
icon: "",
component: BannerManage,
role:["ceo"]
},
{
key: "/home/activityManage",
label: "活动管理",
icon: "",
component: ActivityManage,
role:["cto"]
},
{
key: "/userManage",
label: "用户管理",
icon: "",
// component:"",
role:["ceo"],
children: [
{
key: "/home/register",
label: "注册用户管理",
icon: "",
component: Register,
role:["ceo"]
},
{
key: "/home/admin",
label: "用户后台管理",
icon: "",
component: admin,
role:["ceo"]
}
]
},
]
export default items
Iitems是我封装的ts
export interface Iitems {
key: string,
label: string
icon?: any
children?: Iitems[]
component?: any
role?: string[]
}
仓库里的东西
export default {
namespace: "global",
state: {
// token都懂吧
token: "",
// roles是我的权限
roles: [],
},
reducers: {
savaToken(state: any, { payload }: any) {
// console.log(payload);
// console.log(state);
return { ...state, ...payload }
}
}
}
封装动态路由
import { useSelector } from "dva";
import { useEffect, useState } from "react";
import menus from "../pages/home/menu.config"
import { Iitems } from "../ts/ts"
export default function useFetchMenus() {
const [currentMenus, setCurrentMenus] = useState<Iitems[]>([])
const global = useSelector(({ global }: any) => global)
useEffect(() => {
let currentMenus = getMenus(menus)
setCurrentMenus(currentMenus)
}, [])
const getMenus = (allMenus: Iitems[]) => {
return allMenus.filter((item: Iitems) => {
if (item.children) {
item.children = getMenus(item.children)
}
// console.log(item.role);
return item.role?.some((value) => global.roles.includes(value))
})
}
return {
currentMenus
}
}
动态渲染菜单用的插件,直接引用Ant Design菜单插件就好
<Menu theme="dark" defaultSelectedKeys={[history.location.pathname]} mode="inline" items={currentMenus} onClick={jump} />
动态渲染注册路由
const RenderRoute = (items: Iitems[]) => {
return items.map((item: Iitems, index: number) => {
if (item.children) {
return (
<Switch key={index}>
{RenderRoute(item.children)}
</Switch>
)
} else {
return (
<Route key={item.key} path={item.key} component={item.component} />
)
}
})
}
最后总结思路
登录,获取后端权限,创建路由,封装路由,判断,注册路由,渲染菜单