【react-router-dom】你可能要知道的关于v6.x自定义权限路由的实现

news2024/11/24 12:58:25

路由权限,是webapp或者说后台管理都会需要的业务功能。现在对react-routerv6.x的路由库,封装一个简易的权限路由,实现思路:

后台登录效果

请添加图片描述

代码实现

思路就是对路由表迭代出来的路由,用一个HOC来进行拦截,在真实进入路由之前提前做一些事情,获取用户信息判断权限,token数据,根据不同的状态来决定渲染各自的页面。

  • 项目结构
    在这里插入图片描述
  • 依赖库版本
"dependencies": {
    "@testing-library/jest-dom": "^5.17.0",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router": "^6.28.0",
    "react-router-dom": "^6.28.0",
    "react-scripts": "5.0.1",
    "web-vitals": "^2.1.4"
},
  • router/routes.js
import { Navigate } from "react-router-dom";
import { lazy } from "react";
import Home from "../pages/Home.jsx";
export default [
  {
    path: "/",
    name: "index",
    component: () => <Navigate to="/home" replace />,
  },
  {
    path: "/home",
    name: "home",
    component: Home,
    meta: {
      title: "Home",
      description: "Home page",
    },
  },
  {
    path: "/boss",
    name: "boss",
    component: lazy(() => import("../pages/Boss.jsx")),
  },
  {
    path: "/detail/:id",
    name: "detail-detail",
    component: lazy(() => import("../pages/Detail.jsx")),
  },
  {
    path: "/user",
    name: "User",
    component: lazy(() => import("../pages/User.jsx")),
  },
  {
    path: "/login",
    name: "Login",
    component: lazy(() => import("../pages/Login.jsx")),
  },
  {
    path: "*",
    name: "not-found",
    component: lazy(() => import("../pages/404.jsx")),
  },
];
  • router/index.js
import routesList from "./routes";
import {
  Routes,
  Route,
  useLocation,
  useNavigate,
  useParams,
  useSearchParams,
  NavLink,
} from "react-router-dom";
import { Suspense, useEffect } from "react";
const whiteLists = ["/login"];

function Element({ component: Component, ...rest }) {
  const location = useLocation();
  const navigate = useNavigate();
  useEffect(() => {
    if (
      !whiteLists.includes(location.pathname) &&
      !localStorage.getItem("token")
    ) {
      navigate("/login");
    } else if (
      location.pathname === "/login" &&
      localStorage.getItem("token")
    ) {
      navigate("/");
    }

    return () => {};
  }, [navigate]);
  return <Component {...rest}></Component>;
}
function createRouter() {
  return (
    <>
      {routesList.map((route, index) => {
        return (
          <Route
            key={route.name}
            path={route.path}
            element={<Element {...route} />}
          />
        );
      })}
    </>
  );
}

export default function RouterView() {
  return (
    <>
      <Suspense fallback={<div>Loading...</div>}>
        <Routes>{createRouter()}</Routes>
      </Suspense>
      <div style={{ textAlign: "center" }}>
        <NavLink to="/"> home </NavLink> | <NavLink to="/boss">Boss</NavLink> |{" "}
        <NavLink to="/user">User</NavLink>
      </div>
    </>
  );
}

export function WithRouter(Component) {
  return function Hoc(props) {
    // 提前获取路由信息,传递给组件
    const location = useLocation(),
      navigate = useNavigate(),
      params = useParams(),
      [usp] = useSearchParams();
    const pathObj = { location, navigate, params, usp };
    return <Component {...props} {...pathObj} />;
  };
}
  • pages/Login.jsx
import { useNavigate } from "react-router-dom";
function Login() {
  const navigate = useNavigate();
  function handleSubmit() {
    window.localStorage.setItem("token", "admin");
    navigate("/");
  }
  return (
    <div
      style={{ display: "flex", justifyContent: "center", margin: "20px auto" }}
    >
      <form>
        <input type="text" name="username" placeholder="Username" /> <br />
        <br />
        <input type="password" name="password" placeholder="Password" /> <br />
        <br />
        <button onClick={handleSubmit}>Login</button>
      </form>
    </div>
  );
}
export default Login;
  • pages/User.js
import { useNavigate } from "react-router-dom";
function User() {
  const navigate = useNavigate();
  function handleClick() {
    localStorage.removeItem("token");
    navigate("/login");
  }
  return (
    <div>
      <h1>User Page</h1>
      <p>This is the user page.</p>
      <div>
        <button onClick={handleClick}>退出登录</button>
      </div>
    </div>
  );
}

export default User;

体验优化

上面的效果会存在比较明显的闪烁,优化代码如下


function Element({ component: Component, ...rest }) {
  const location = useLocation();
  const navigate = useNavigate();
  if (
    !whiteLists.includes(location.pathname) &&
    !localStorage.getItem("token")
  ) {
    navigate("/login");
  } else if (location.pathname === "/login" && localStorage.getItem("token")) {
    navigate("/");
  }
  return <Component {...rest}></Component>;
}

请添加图片描述
对HOC组件的渲染逻辑进行改写,页面切换的时候体验好了很多。

总结

这只是简易的封装了下路由结构,没考虑二级路由或者多级的情况,思路就是这么思路,可以自行去实现下。

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

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

相关文章

贪心算法day05(k次取反后最大数组和 田径赛马)

目录 1.k次取反后最大化的数组和 2.按身高排序 3.优势洗牌 1.k次取反后最大化的数组和 题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 代码&#xff1a; class Solution {public int largestSumAfterKNegations(int[] nums, int k) {//如…

AI(11)-海报制作

1-画板 2-【矩形工具】 130x20&#xff1a;2个 100x10&#xff1a;1个 200x30&#xff1a;1个 3-参数调整 3-1-【颜色&#xff1a;65&#xff0c;10&#xff0c;40&#xff0c;0】&#xff0c;【无描边】 4-【shift】【倾斜工具】-调整矩形形状 4-1-单独调整一个矩形 4-2…

cherno引擎课 -

感谢b站星云图形的翻译&#xff1a;【双语】【最佳游戏引擎教程实战】【入门】&#xff08;1&#xff09;&#xff1a;Introducing the GAME ENGINE series!_哔哩哔哩_bilibili Introducing the GAMEENGINE series 希望&#xff1a;它是一个制作(互动)3D实时渲染应用程序的引…

Linux git-bash配置

参考资料 命令提示符Windows下的Git Bash配置&#xff0c;提升你的终端操作体验WindowsTerminal添加git-bash 目录 一. git-bash配置1.1 解决中文乱码1.2 修改命令提示符 二. WindowsTerminal配置git-bash2.1 添加git-bash到WindowsTerminal2.2 解决删除时窗口闪烁问题 三. VS…

秃姐学AI系列之:GRU——门控循环单元 | LSTM——长短期记忆网络

RNN存在的问题 因为RNN模型的BPTT反向传导的链式求导&#xff0c;导致需要反复乘以一个也就是说会出现指数级别的问题&#xff1a; 梯度爆炸&#xff1a;如果的话&#xff0c;那么连乘的结果可能会快速增长&#xff0c;导致梯度爆炸梯度消失&#xff1a;如果的话&#xff0c;…

Java面试要点06 - static关键字、静态属性与静态方法

本文目录 一、引言二、静态属性&#xff08;Static Fields&#xff09;三、静态方法&#xff08;Static Methods&#xff09;四、静态代码块&#xff08;Static Blocks&#xff09;五、静态内部类&#xff08;Static Nested Classes&#xff09;六、静态导入&#xff08;Static…

【测试】【Debug】vscode pytest 找不到测试用例测试文件 行号部位没有绿色箭头

出现这种情况首先检查&#xff1a; 是否安装pytest点击vscode的这个图标如果其中都是空的&#xff0c;没有识别上&#xff0c;并且写好的.py测试文件的行号前面没有运行符号&#xff0c;要检查名称是否按照pytest的要求写&#xff0c;不然会识别不到。 命名规则注意&#xff1…

区块链技术在电子政务中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 区块链技术在电子政务中的应用 区块链技术在电子政务中的应用 区块链技术在电子政务中的应用 引言 区块链技术概述 定义与原理 发…

【Java Web】Servlet

文章目录 Servlet APIServlet生命周期Servlet配置注解配置文件全局参数 Servlet获得内置对象升级示例3 Servlet 是一种用于构建 Java 服务器端应用程序的技术&#xff0c;允许开发者创建动态的 web 内容。Servlets 在 Java 平台上运行&#xff0c;并由 Java Servlet API 提供支…

linux命令详解,存储管理相关

存储管理 一、内存使用量&#xff0c;free free 命令是一个用于显示系统中物理内存&#xff08;RAM&#xff09;和交换空间&#xff08;swap&#xff09;使用情况的工具 free -m free -m -s 5参数 -b 功能: 以字节&#xff08;bytes&#xff09;为单位显示内存使用情况。说…

流体力学ansys Fluent二次开发scheme_eval模块剖析

在ANSYS Fluent的二次开发中&#xff0c;scheme_eval 是 Scheme 编程语言中一个非常重要的模块&#xff0c;它允许用户执行动态的 Scheme 表达式和函数&#xff0c;从而扩展 Fluent 的功能。scheme_eval 模块通常与 Fluent 的计算和自定义脚本操作紧密结合。下面我们会对这个模…

中仕公考:大四在校生考公怎么规划?

还在就读的大学生&#xff0c;大三下学期就可以备考&#xff0c;大四以应届生的身份参加考试&#xff0c;中仕不建议大家把备考战线拉得太长或者太短&#xff0c;时间太长容易疲惫&#xff0c;时间太短容易备考不到位。 考公流程&#xff1a; 查看公告职位表→网上报名一资格…

【363】基于springboot的高校竞赛管理系统

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统高校竞赛管理系统信息管理难度大&#xff0c;容错率低&am…

网站架构知识之Ansible模块(day021)

1.Ansible模块 作用:通过ansible模块实现批量管理 2.command模块与shell模块 command模块是ansible默认的模块&#xff0c;适用于执行简单的命令&#xff0c;不支持特殊符号 案列01&#xff0c;批量获取主机名 ansible all -m command -a hostname all表示对主机清单所有组…

计算机网络:网络层 —— 软件定义网络 SDN

文章目录 软件定义网络 SDN远程控制器OpenFlow协议SDN 广义转发流表简单转发负载均衡防火墙 SDN 控制器 软件定义网络 SDN 软件定义网络&#xff08;Software Defined Networking&#xff0c;SDN&#xff09;是一种新兴的网络架构&#xff0c;旨在通过网络控制与数据转发的分离…

使用 .NET Core 7 和 SignalR 构建实时聊天应用程序

动动你可爱的小手&#xff0c;请关注下本人公众号&#xff0c;继续为您提供更多原创技术文章。谢谢给为的支持 SignalR 是一个 ASP.NET 库&#xff0c;它支持实时 Web 功能&#xff0c;允许服务器立即将更新推送到客户端&#xff0c;从而提高应用程序的效率和响应能力。它通过简…

响应式网页设计--html

一&#xff0c;HTML 文档的基本结构 一个典型的 HTML 文档包含了几个主要部分&#xff0c;基本结构如下(本文以下出现的所有代码都可以套入下面示例进行测试)&#xff1a; <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8&q…

欢迎 Stable Diffusion 3.5 Large 加入 Diffusers

作为Stable Diffusion 3的改进版本&#xff0c;Stable Diffusion 3.5 如今已在 Hugging Face Hub 中可用&#xff0c;并可以直接使用 &#x1f9e8; Diffusers 中的代码运行。 https://hf.co/blog/sd3 本次发布包含两套模型参数: https://hf.co/collections/stabilityai/stable…

Ubuntu22.04中使用CMake配置运行boost库示例程序

Ubuntu22.04中使用CMake配置运行boost库示例程序 boost是一个比较强大的C准标准库&#xff0c;里面有很多值得学习的东西&#xff0c;比较asio网络库可以用来编写C TCP客户端或者TCP服务端接收程序。本文主要讲解如何在Ubuntu22.04中使用Cmake配置boost库&#xff0c;以及运行…

高效档案管理案例介绍:文档内容批量结构化解决方案解析

一、项目背景介绍 档案文件中包含的内容丰富且形式多样&#xff0c;通常不仅包括文本&#xff0c;还可能包含表格、图片、标题、段落、注释等多种内容元素。传统的档案管理往往依赖人工对文档内容进行归档、分类和标注&#xff0c;这种方式耗时费力&#xff0c;且在管理庞大数…