react根据后端返回数据动态添加路由

以下代码都为部分核心代码

一.根据不同的登录用户,返回不同的权限列表 ,以下是三种不同用户限权列表

const pression = {
//超级管理员BigAdmin: [{key: "screen",icon: "FileOutlined",label: "数据图表",},{key: "users",icon: "UserOutlined",label: "用户列表",},{key: "food",icon: "PieChartOutlined",label: "食谱",},{key: "discuss",icon: "CommentOutlined",label: "评论",}],
//普通管理员Admin: [{key: "screen",icon: "FileOutlined",label: "数据图表",},{key: "food",icon: "PieChartOutlined",label: "食谱",}, {key: "discuss",icon: "CommentOutlined",label: "评论",}],
//普通用户commont: [{key: "screen",icon: "FileOutlined",label: "数据图表",}]}

二.实现动态菜单

用户登录后先将权限列表存入本地浏览器,再跳转到系统页面,并在首次加载时候获取本地权限列表数据,进行动态渲染

//假如登录的是超级管理员,对应的权限列表应如下,这里使用了ant design的菜单组件,为了方便所以使用符合该菜单组件的数据结构BigAdmin: [{key: "screen",icon: "FileOutlined",label: "数据图表",},{key: "users",icon: "UserOutlined",label: "用户列表",},{key: "food",icon: "PieChartOutlined",label: "食谱",},{key: "discuss",icon: "CommentOutlined",label: "评论",}],
//-----------------import * as Icons from '@ant-design/icons';//--自定义组件将字符串转化为对应的组件---------
const ICONFONT = (props: any) => {const { icon } = props//动态菜单不能确定需要那些icon,全部引入作为Iconsreturn React.createElement(Icons[icon])
}const [Enums, setenum] = useState<any>()const AdminInfo = useSelector((state: any) => state.AdminStore.AdminInfo)
useEffect(() => {
//登录后,系统首页获取本地权限列表,因为这里使用了ant design的icon,需要将字符串转化为对应的组件,这里封装的自定义组件let items = JSON.parse(JSON.stringify(AdminInfo.pression))items.map((item: any) => {item.icon = item.icon && <ICONFONT icon={item.icon}></ICONFONT>})setenum([...items])}, [])//在菜单组件中使用<Menu selectedKeys={['screen']} mode="inline" items={Enums} onClick={chooose} />

三.实现动态路由 

先把动态路由和静态路由分离出来,在路由配置文件中,这里需要进行动态添加的路由为 path: "/backstage"下的子路由,需要给他一个name,后续方便查找


//这里也很重要,页面加载时候,先判断本地是否存入了权限列表
import { Admin } from "@/utils/local"
//获取本地存储的信息
const rs = Admin.get_Admin()//路由懒加载
const lazyComponent = (Component: FC) => {return <Suspense fallback={Skeletons}><Component /></Suspense>
}//静态路由
const routers = [{path: '/',element: <Navigate to="/home" />},{path: "/",element: <App />,children: [{path: "/home",element: lazyComponent(Home),},{path: "/category",element: lazyComponent(About),children: [{path: "/category",element: <Navigate to={'/category/mainfood'}></Navigate>},{path: "mainfood",element: lazyComponent(Mainfood)},{path: "bake",element: lazyComponent(Bake)},{path: "beverage",element: lazyComponent(Beverage)},{path: "soup",element: lazyComponent(Soup)}]}, {path: "/user",element: lazyComponent(Test),}, {path: "/edituser",element: lazyComponent(EeditUser)},{path: "/editfood",element: lazyComponent(Edit_Food)}]},{path: "/detaile/:id",element: lazyComponent(Datile)},{path: "/login",element: <Login></Login>},{
//需要动态添加的路由在此处path: "/backstage",element: lazyComponent(Back),name: "back",children: [{path: "/backstage",element: <Navigate to="/backstage/screen"></Navigate>},{path: "screen",element: lazyComponent(Screen)},]},{path: "*",element: <Error></Error>}
]//准备需要添加的动态路由,将添加到 path: "/backstage"的子路由下,
//这里的id必须必须填写,而且必须唯一, 
//如:id:'4-2',4表示在一级路由下索引为4的路由,2表示在该路由下子路由的索引
const dtRoute = [{path: "users",element: lazyComponent(Users),id: '4-2'},{path: "food",id: '4-3',element: lazyComponent(Food)},{path: "discuss",id: '4-4',element: lazyComponent(Discuss)}
]

定义一个动态添加路由的函数

const dtRoute = [{path: "users",element: lazyComponent(Users),id: '4-2'},{path: "food",id: '4-3',element: lazyComponent(Food)},{path: "discuss",id: '4-4',element: lazyComponent(Discuss)}
]const route = createBrowserRouter(routers)//这里需要导出函数,在登录后调用,pression即为后端返回的列表
export function addrouter(pression: any[]) {
//找到需要动态添加的路由,name为back,即为之前的path:"/backstage"路由const baseRouter = route.routes.find((rt: any) => rt.name === "back")console.log(baseRouter)if (pression.length !== 0) {//判断传入的权限列表是否在动态路由之中,有则追加进去for (const use of pression) {for (const rt of dtRoute) {if (rt.path === use.key) {baseRouter?.children?.push(rt)} else {}}}} else {
//如果传入的为空表示,退出登录,更新路由,这里取的最前两个静态路由,即删除动态路由baseRouter?.children?.splice(2)}
}//这里之前已提到,
import { Admin } from "@/utils/local"
const rs = Admin.get_Admin()
//-------页面刷新时候会重新执行路由文件---访问其它动态路由的时候会丢失找不到,
//因为动态路由只在登录的时候进行了添加,而页面刷新会让整个路由重新执行,而不会重新动态添加--
//所以刷新的时候要判断本地是否存储了动态路由信息,并再次添加
if (rs) {addrouter(rs.pression)
}

在redux中使用动态添加路由的函数

import { createSlice } from "@reduxjs/toolkit";
import { Admin } from "@/utils/local";
import { Admin_Loing } from '@/apis/admin/admin'
import { message } from "antd"
import type { AppDispatch } from "../index"//导入动态添加路由的函数
import { addrouter } from "@/router"
const AdminStore = createSlice({name: "RootStore",initialState: {AdminInfo: Admin.get_Admin() || {pression: [],user: {}}},reducers: {//定义登录方法,需要在登录后动态添加路由Login: (state, { payload }) => {state.AdminInfo = payloadAdmin.set_Admin(payload)
//调用动态添加路由的函数,并传入登录后传来的权限列表addrouter(payload.pression)},GoOut: (state) => {state.AdminInfo = {pression: [],user: {}}Admin.remove_Admin()addrouter([])},},
})//导出Login
export const { Login, GoOut } = AdminStore.actions//,登录是异步的,所以定义异步登录方法
const axios_admin_login = (data: any) => {return async (dispatch: AppDispatch) => {const res = await Admin_Loing(data)if (res.status == 200) {
//登录成功后调用Login,并传入包含权限列表的数据dispatch(Login(res.data))message.success("登录成功")return true} else {return false}}
}
//最后导出异步登录,在登录界面使用
export { axios_admin_login }
export default AdminStore.reducer

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/43150.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

谷粒商城学习笔记-使用renren-fast-vue框架时安装依赖包遇到的问题及解决策略

文章目录 1&#xff0c;npm error Class extends value undefined is not a constuctor or null2&#xff0c;npm warn cli npm v10.8.1 does not support Node.js v16.20.2.3&#xff0c;npm error code CERT_HAS_EXPIRED学习心得 这篇文章记录下使用renren-fast-vue&#xff…

QT学习(6)——QT中的定时器事件,两种实现方式;事件的分发event,事件过滤器

目录 引出定时器事件QTimerEventQTimer 事件的分发事件过滤器 总结QT中的鼠标事件定义QLable的鼠标进入离开事件提升为myLabel重写QLabel的函数鼠标的事件鼠标的左中右键枚举鼠标多事件获取和鼠标移动鼠标追踪 QT中的信号和槽自定义信号和槽1.自定义信号2.自定义槽3.建立连接4.…

C++ 类和对象 拷贝构造函数

一 拷贝构造函数的概念&#xff1a; 拷贝构造函数是一种特殊的构造函数&#xff0c;用于创建一个对象是另一个对象的副本。当需要用一个已存在的对象来初始化一个新对象时&#xff0c;或者将对象传递给函数或从函数返回对象时&#xff0c;会调用拷贝构造函数。 二 拷贝构造函…

打卡第6天----哈希表

每天进步一点点,滴水石穿,日积月累,不断提升。 数组和链表章节告一段落。开启哈希表相关的。 哈希表能解决什么问题呢,一般哈希表都是用来快速判断一个元素是否出现集合里 一、有效的字母异位词 leetcode题目编号:242 题目描述: 给定两个字符串 s 和 t ,编写一个函数…

安装和配置 MSYS2

MSYS2&#xff08;Minimal SYStem 2&#xff09;是一个为Windows平台提供的轻量级Linux类系统&#xff0c;它集成了大量的GNU工具链、工具和库&#xff0c;为开发者提供了一个类似于Linux的shell环境和完整的开发环境。以下是关于MSYS2的详细介绍&#xff1a; 一、定义与特点 …

深入理解Java中的泛型编程

深入理解Java中的泛型编程 大家好&#xff0c;我是微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 1. 泛型的基础概念 在Java中&#xff0c;泛型编程是一种强大的编程范式&#xff0c;它允许我们编写可以操作各种类型的代…

vagrant远程连接不上问题

如果使用的是vbox虚拟机的host_only的默认ip为56.1开头如果使用这个1作为地址&#xff0c;只能使用转发的形式连接&#xff0c;宿主机使用ssh -p 22222 name127.0.0.1 连接&#xff0c;如果配置的主机位大于1则可以使用虚拟机的ip地址连接。 1使用网络地址转换&#xff08;ant…

Linux忘记密码重置root密码、重置普通用户密码

重启看到选项按e reboot 或 init 62、移动到Linux开头的行在末尾添加 rw init/bin/bash3、按下Ctrlx引导启动 mount -o remount,rw /输入命令回车更改密码,输入新密码&#xff0c;别用小键盘&#xff0c;容易出错 passwd输入两次校验&#xff0c;出现updated successfully就…

OceanBase 配置项系统变量实现及应用详解(1):配置项的定义及使用方法

《OceanBase 配置项&系统变量实现及应用详解》专题导读 在使用OceanBase的过程中&#xff0c;看到大家经常会遇到“参数”、“配置项”、“系统变量”等概念&#xff0c;却不太清楚它们是不是同一个东西&#xff0c;以及应该如何使用。一些对数据库开发感兴趣的朋友&#…

开源大模型对比

随着chatgpt诞生&#xff0c;开源大模型的也获得了突飞猛进的进展&#xff0c;值得关注的是国内本地私有大模型已经在很多真实的场景中落地&#xff0c;比如智能客服。美国的技术研发能力遥遥领先&#xff0c;但是不得不说落地应用这块是我们的强项。企业使用大模型一般需要考虑…

【面向就业的Linux基础】从入门到熟练,探索Linux的秘密(九)-git(1)

Git是一个版本管理控制系统&#xff08;缩写VCS&#xff09;&#xff0c;它可以在任何时间点&#xff0c;将文档的状态作为更新记录保存起来&#xff0c;也可以在任何时间点&#xff0c;将更新记录恢复回来。 文章目录 前言 一、git是什么 二、git基本概念 三、git基本命令 总结…

电商项目中分与元金额单位互转实战

在Java开发中&#xff0c;可能遇到金额单位的转换&#xff0c;比如本系统用分作为金额的基本单位&#xff0c;对方系统用元作为金额的基本单位&#xff0c;这就需要进行单位转换&#xff0c;记录下来&#xff0c;方便备查。 一、分转元 分转元&#xff0c;分到元相差两位&…

PHP源码:新闻门户系统(附管理后台+前台)

一. 前言 今天小编给大家带来了一款可学习&#xff0c;可商用的&#xff0c;新闻门户系统 源码&#xff0c;支持二开&#xff0c;无加密。项目可以扩展为个人博客&#xff0c;和一些社交论坛网址。主要功能&#xff1a;支持文章管理&#xff0c;评论管理&#xff0c;分类管理等…

Kotlin linkedMapOf filterKeys

Kotlin linkedMapOf filterKeys fun main(args: Array<String>) {val lhm linkedMapOf<String, Any>(Pair("name", "phil"), //因为key相同都为 name&#xff0c;被后面的覆盖。Pair("year", 2024),Pair("name", "f…

大语言模型的应用探索AI Agent初探!

前言 大语言模型的应用之一是与大语言模型进行聊天也就是一个ChatBot&#xff0c;这个应用已经很广泛了。 接下来的一个应用就是AI Agent。 AI Agent是人工智能代理&#xff08;Artificial Intelligence Agent&#xff09;的概念&#xff0c;它是一种能够感知环境、进行决策…

消防认证-防火窗

一、消防认证 消防认证是指消防产品符合国家相关技术要求和标准&#xff0c;且通过了国家认证认可监督管理委员会审批&#xff0c;获得消防认证资质的认证机构颁发的证书&#xff0c;消防产品具有完好的防火功能&#xff0c;是住房和城乡建设领域验收的重要指标。 二、认证依据…

GEE代码实例教程详解:NDVI时间序列趋势分析

简介 在本篇博客中&#xff0c;我们将使用Google Earth Engine (GEE) 对MODIS NDVI数据进行时间序列趋势分析。通过分析2001年至2021年的NDVI数据&#xff0c;我们可以了解植被覆盖度随时间的变化趋势。 背景知识 MODIS数据集 MODIS&#xff08;Moderate Resolution Imagin…

Websocket在Java中的实践——整合Rabbitmq和STOMP

大纲 Rabbitmq开启STOMP支持 服务端依赖参数参数映射类配置类逻辑处理类 测试测试页面Controller测试案例 在《Websocket在Java中的实践——STOMP通信的最小Demo》一文中&#xff0c;我们使用enableSimpleBroker启用一个内置的内存级消息代理。本文我们将使用Rabbitmq作为消息代…

【Unity2D 2022:Particle System】添加拾取粒子特效

一、创建粒子特效游戏物体 二、修改粒子系统属性 1. 基础属性 &#xff08;1&#xff09;修改发射粒子持续时间&#xff08;Duration&#xff09;为3s &#xff08;2&#xff09;取消勾选循环&#xff08;Looping&#xff09; &#xff08;2&#xff09;修改粒子存在时间&…