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,全部引入作为Icons
    return 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 = payload

            Admin.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.mfbz.cn/a/784519.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

企业如何从无序管理走向精益生产管理?

先来看看企业生产管理无序的弊端有哪些&#xff1f; 数据统计不及时&#xff1a;纸质生产工单&#xff0c;数据难统计&#xff0c;各业务环节问题难定位&#xff0c;影响车间生产效率。生产过程不透明&#xff1a;生产过程数据难监控&#xff0c;生产派工管理混乱&#xff0c;…

百度网盘非会员,享受视频倍速

百度网盘会员过期了&#xff0c;看视频不能倍速很难受&#xff0c;下面就是跨过会员机制&#xff0c;享受倍速的方法。 Edge浏览器 在浏览器设置中找到扩展选项 在扩展中搜索视频速度控制 global speed&#xff0c;安装后即可使用

在Linux操作系统中去修复/etc/fstab文件引起的系统故障。

如果/etcfstab文件中发生错误&#xff0c;有可能导致系统无法正常启动。 比如&#xff1a;系统里的一块磁盘被删除&#xff0c;但是/etc/fstab中关于这块磁盘的信息依然被保存在文件/etc/fstab中。 主要看倒数后两行&#xff0c;系统提示&#xff0c;敲ctrlD或者是直接输入密码…

2通道音频ADC解码芯片ES7243L、ES7243E、ES7243,用于低成本实现模拟麦克风转换为IIS数字话筒

前言&#xff1a; 音频解码芯片某创参考价格&#xff1a; ES7243L 500&#xff1a;&#xffe5;1.36 / 个 ES7243E 500&#xff1a;&#xffe5;1.66 / 个 ES7243 500&#xff1a; &#xffe5;1.91 / 个 其中ES7243L工作电压为1.8V&#xff0c;与其他两款的3.3V工作电压不同&…

推荐3款免费电脑工具

Tools-Web Tools-Web是一个在线工具箱&#xff0c;提供丰富的工具和功能&#xff0c;适用于日常工作和学习。根据用户评价&#xff0c;Tools-Web的工具种类丰富且操作简单&#xff0c;是日常工作和学习的好帮手。该工具箱涵盖了开发运维、文本处理、图片处理、图表处理、随机工…

大模型知识问答: 文本分块要点总结

节前&#xff0c;我们组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、今年参加社招和校招面试的同学。 针对大模型技术趋势、算法项目落地经验分享、新手如何入门算法岗、该如何准备面试攻略、面试常考点等热门话题进行了深入的讨论。 总结链接如…

昇思MindSpore学习笔记6-01LLM原理和实践--FCN图像语义分割

摘要&#xff1a; 记录MindSpore AI框架使用FCN全卷积网络理解图像进行图像语议分割的过程、步骤和方法。包括环境准备、下载数据集、数据集加载和预处理、构建网络、训练准备、模型训练、模型评估、模型推理等。 一、概念 1.语义分割 图像语义分割 semantic segmentation …

【易捷海购-注册安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

【2024华为HCIP831 | 高级网络工程师之路】刷题日记(BGP)

个人名片:🪪 🐼作者简介:一名大三在校生,喜欢AI编程🎋 🐻‍❄️个人主页🥇:落798. 🐼个人WeChat:hmmwx53 🕊️系列专栏:🖼️ 零基础学Java——小白入门必备🔥重识C语言——复习回顾🔥计算机网络体系———深度详讲HCIP数通工程师-刷题与实战🔥🔥

windows obdc配置

进入控制面板&#xff1a; 进入管理工具&#xff1a;

java —— JSP 技术

一、JSP &#xff08;一&#xff09;前言 1、.jsp 与 .html 一样属于前端内容&#xff0c;创建在 WebContent 之下&#xff1b; 2、嵌套的 java 语句放置在<% %>里面&#xff1b; 3、嵌套 java 语句的三种语法&#xff1a; ① 脚本&#xff1a;<% java 代码 %>…

顶会FAST24最佳论文|阿里云块存储架构演进的得与失-4.EBS不同架构性能提升思路

3.1 平均延迟与长尾延迟 虚拟磁盘&#xff08;VD&#xff09;的延迟是由其底层架构决定的&#xff0c;具体而言&#xff0c;取决于请求所经历的路径。以EBS2为例&#xff0c;VD的延迟受制于两跳网络&#xff08;从BlockClient到BlockServer&#xff0c;再至ChunkServer&#x…

机器学习统计学基础 - 最大似然估计

最大似然估计&#xff08;Maximum Likelihood Estimation, MLE&#xff09;是一种常用的参数估计方法&#xff0c;其基本原理是通过最大化观测数据出现的概率来寻找最优的参数估计值。具体来说&#xff0c;最大似然估计的核心思想是利用已知的样本结果&#xff0c;反推最有可能…

零知识证明技术:隐私保护的利器

在当今信息时代&#xff0c;数据安全和隐私保护的重要性日益凸显。随着技术的发展&#xff0c;密码学在保障信息安全方面发挥着越来越重要的作用。其中&#xff0c;零知识证明技术作为一种新兴的密码学方法&#xff0c;为隐私保护提供了强有力的支持。本文将简要介绍零知识证明…

一.4 处理器读并解释储存在内存中的指令

此刻&#xff0c;hello.c源程序已经被编译系统翻译成了可执行目标文件hello&#xff0c;并被存放在硬盘上。要想在Unix系统上运行该可执行文件&#xff0c;我们将它的文件名输入到称为shell的应用程序中&#xff1a; linux>./hello hello, world linux> shell是一个命令…

[Flink]二、Flink1.13

7. 处理函数 之前所介绍的流处理 API,无论是基本的转换、聚合,还是更为复杂的窗口操作,其实都是基于 DataStream 进行转换的;所以可以统称为 DataStream API ,这也是 Flink 编程的核心。而我们知道,为了让代码有更强大的表现力和易用性, Flink 本身提供了多…

【面试题】串联探针和旁挂探针有什么区别?

在网络安全领域中&#xff0c;串联探针和旁挂探针&#xff08;通常也被称为旁路探针&#xff09;是两种不同部署方式的监控设备&#xff0c;它们各自具有独特的特性和应用场景。以下是它们之间的主要区别&#xff1a; 部署方式 串联探针&#xff1a;串联探针一般通过网关或者…

@react-google-maps/api实现谷歌地图嵌入React项目中,并且做到点击地图任意一处,获得它的经纬度

1.第一步要加入项目package.json中或者直接yarn install它都可以 "react-google-maps/api": "^2.19.3",2.加入项目中 import AMapLoader from amap/amap-jsapi-loader;import React, { PureComponent } from react; import { GoogleMap, LoadScript, Mar…

【刷题笔记(编程题)05】另类加法、走方格的方案数、井字棋、密码强度等级

1. 另类加法 给定两个int A和B。编写一个函数返回AB的值&#xff0c;但不得使用或其他算数运算符。 测试样例&#xff1a; 1,2 返回&#xff1a;3 示例 1 输入 输出 思路1: 二进制0101和1101的相加 0 1 0 1 1 1 0 1 其实就是 不带进位的结果1000 和进位产生的1010相加 无进位加…

虚拟地址空间划分

记住&#xff1a;任何编程语言编译之后产生汇编指令数据 每一个进程的用户空间是私有的&#xff0c;内核空间是共享的(管道通信的原理) X86 32为linux环境下,虚拟地址空间结构 只读区&#xff1a; .text段:指令段&#xff0c;存放汇编指令 .rodata段:常量段&#xff0c;存放常…