权限
路由的接口类型为Array
菜单的接口类型为MenuProps[‘items’], 为antd中结构,官网有
1、创建切片
import {createSlice,PayloadAction,Dipatch} from 'RTK';
// 导入接口
// initialState的类型是自定义的接口 IAuthInitalState
// IAuthInitalState的成员menus的类型Menus['props']
import {IAuthInitalState} from '接口文件地址'
导入转化工具
import {transfromRightMenus} from '../utils'
const initialState:IAuthInitalState = {
menus:[]
routes:[]
}
const authSlice = createSlice({
name:'authNs'
initialState,
reducers:{
getMenus(state:IAuthInitalState,{payload}:PayloadAction<any>[]){
state.menus = payload
}
}
})
export const getMenusAync = (dipatch:Dipatch)=>{
let ary = transfromRightMenus(result.data.data)
dipatch(getMenus(ary))
}
export const {getMenus} = authSlice.actions
export default authSlice.reducer
2、在types文件下创建users接口
import {MenuProps} from 'antd'
export interface IAuthInitalState{
menus:MenuProps['items']
}
// 定义规范权限数据对象的接口
export interface IrightData{
_id:string,
title:string,
pid:string,
path:string,
icon:string,
children?:IrightData[]
}
// 定义规范AntdMenu对象的接口
export interface IAntdMenuItem{
label:string
key:string
icon:React.ReactNode,
children?:Array<IAntdMenuItem>
}
3、仓库入口文件配置
import { configureStroe} from 'RTK'
import auth from 'auth'
const store = configureStroe({
reducer:{
auth
},
middleWare:()=>{}
})
export default store
4、项目入口文件
import store from ' 仓库入口文件地址'
const root = ReactDom.createRoot(document.querSelector('root'))
root.render(
<BrowserRouter >
<Provider store={store}>
<App />
</Provider>
</BrowserRouter>
)
5、创建NavigateMenu组件
import React,{useEffect} from 'react'
// 这里不要导入useDipatch
// import {useDipatch} from 'react-redux'
// 导入useAppDipatch,这样dispatch(getMenusAync)不会报类型限制错
import {useAppDipatch,useAppSelector} from './store/hooks'
// 导入reducer
import {getMenusAync} from 'reducer地址'
//导入antd
import {Menus} from 'antd'
export default function NavigateMenu(){
const dispatch = useAppDipatch()
useEffect(()=>{
dispatch(getMenusAync)
})
const items = useAppSelector((state)=>{
return state.auth.menus
})
}
6、 在store的创建hooks.tsx文件
import { useDispatch, useSelector } from 'react-redux'
import type { TypedUseSelectorHook } from 'react-redux'
import type { RootState, AppDispatch } from './index'
// Use throughout your app instead of plain `useDispatch` and `useSelector`
export const useAppDispatch: () => AppDispatch = useDispatch
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector
7、菜单转化,创建authUtils工具文件
1. 导入菜单接口限制
import {IRightData,IAntdMenuItem} from '@/接口地址'
2. 引入antd图标库
import * as icons from '@antd-deign/icons'
2. 将权限数据转成AuthMenu结构数据
export const transfromRightMenus = (list:Array<IRightData>)=>{
return list.map(item=>{
let menuItem:IAntdMenuItem
// 3.判断icon图标
if(item.icon){
// keyof的作用是将一个对象中的key联合起来作为一个新类型
const iis:any = icons[item.icon as keyof typeof icons]
menuItem={
label:item.title,
key:item.path,
icon:React.createElement(iis)
}
}else{
menuItem ={
laebl:item.titile,
key:item.path
}
}
if(item.children&&item.children.length){
menuItem.children = transfromRightMenus(item.children)
}
return menuItme
})
}
8、在sotre中auth中配置
配置中间件serializableCheck,消除序列化报错
const store = configureStore({
reducer:{
authReducer
},
middleware:(getDefaultMiddleware)=>getDefaultMiddleware({serializableCheck:false})
})