React 像 vue 一样配置页面路由,并支持重定向路由,路由守卫等(使用 useRoutes 完成)

news2025/4/10 0:59:09
  • 希望达到跟 vue 一样,在 js 配置中则完成路由重定向的等基础操作,不太习惯使用 Routes、Route 等互相包裹的方式。

  • 所有基于 react-router-dom@6.15.0 封装了一个路由组件,并附带展示个路由守卫组件。

  • 路由组件 - ExRouter.tsx<ExRouter routes={routes}></ExRouter>

    扩展路由配置,支持重定向,以及方便扩展其他属性。

    // 基于 react-router-dom@6.15.0 封装
    import { useRoutes, Navigate, IndexRouteObject, NonIndexRouteObject } from 'react-router-dom'
    import { useLocation, Location } from 'react-router'
    
    /**
     * @description: 扩展 IndexRouteObject
     */
    interface exIndexRouteObject extends IndexRouteObject {
      /**
       * @description: 重定向路由地址
       */
      redirect?: string
    }
    
    /**
     * @description: 扩展 NonIndexRouteObject
     */
    interface exNonIndexRouteObject extends NonIndexRouteObject {
      /**
       * @description: 重定向路由地址
       */
      redirect?: string
    }
    
    /**
     * @description: 路由对象类型
     */
    export type exRouteObject = exIndexRouteObject | exNonIndexRouteObject
    /**
     * @description: 找到路由对象类型
     */
    export type findExRouteObject = exRouteObject | undefined
    
    /**
     * @description: 组件参数
     */
    type props = {
      /**
       * @description: 路由列表
       */
      routes: exRouteObject[],
      /**
       * @description: 子组件列表
       */
      children?: any
    }
    
    const Component = (props: props) => {
      // 当前导航对象
      const location = useLocation()
      // 找到路由对象
      const findRoute = (routes: exRouteObject[], location: Location): findExRouteObject => {
        // 当前层级检查一轮
        let route: any = routes.find((item: any) => item.path === location.pathname)
        // 没有则搜索当前层级同级子页面
        if (!route) {
          // 排查,找到停止
          routes.some((item: any) => {
            // 取出子列表
            const children: exRouteObject[] = item?.children || []
            // 进行排查
            route = findRoute(children, location) 
            // 有值则暂停
            return !!route
          })
        }
        // 返回
        return route
      }
      // 找到当前路由
      const route: findExRouteObject = findRoute(props.routes, location)
      // 返回渲染
      return (
        <>
          {/* 加载所有路由 */}
          { useRoutes(props.routes) }
          {/* 检查当前路由是否需要重定向 */}
          { route?.redirect && <Navigate to={route.redirect} replace /> }
        </>
      )
    }
    
    export default Component
    
  • 路由拦截(路由守卫)组件:<BeforeEach></BeforeEach>

    // import { Navigate, useLocation, useSearchParams } from 'react-router-dom'
    
    const Component = (props: any) => {
      // // 接收路由参数
      // const [searchParams] = useSearchParams()
      // // 当前导航对象
      // const location = useLocation()
      // // token (检查本地或路由参数)
      // const token = 'xxxx'
      // // console.log(location, searchParams.get('token'))
      // // 路由权限校验
      // if (location.pathname.includes('/login') && token) {
      //   // 跳转登录页 && token有值
      //   return <Navigate to="/home" replace />
      // } else if (!location.pathname.includes('/login') && !token) {
      //   // 不是跳转登录页 && token无值
      //   return <Navigate to="/login" replace />
      // }
      // 验证通过
      return props.children
    }
    
    export default Component
    
  • 上面两个组件在路由中的使用:

    import React from 'react'
    import { Navigate } from 'react-router-dom'
    import BeforeEach from './BeforeEach'
    import ExRouter from './ExRouter'
    
    // 懒加载
    const lazyload = (path: string) => {
      // 加载组件
      let Component=React.lazy(()=>{return import (`@/${path}`)})
      // 返回渲染
      return (
        <React.Suspense fallback={<>请等待·····</>}>
          <Component />
        </React.Suspense>
      )
    }
    
    // 基础路由
    const baseRoutes: Record<string, any>[] = [
      {
        path: '/home',
        element: lazyload('views/home'),
      },
      {
        path: '/user',
        element: lazyload('views/user'),
      },
      {
        path: '/layout',
        redirect: '/layout/home',
        element: lazyload('layouts/BaseLayout'),
        children: [
          {
            path: '/layout/home',
            redirect: '/layout/home/home1',
            element: lazyload('views/home'),
            children: [
              {
                path: '/layout/home/home1',
                element: lazyload('views/home')
              }
            ]
          }
        ]
      }
    ]
    
    // 路由列表
    const routes: Record<string, any>[] = [
      ...baseRoutes,
      {
        path: "/404",
        element: (<>页面地址不存在</>),
      },
      { path: "/", element: <Navigate to="/home" /> },
      { path: "*", element: <Navigate to="/404" /> },
    ]
    
    // 加载配置式路由
    function Router () {
      return (
        <BeforeEach>
          {/* 加载所有路由 */}
          {/* { useRoutes(props.routes) } */}
          {/* 加载所有路由,并扩展路由配置 */}
          <ExRouter routes={routes}></ExRouter>
        </BeforeEach>
      )
    }
    
    // 导出
    export default Router
    

    test.gif

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

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

相关文章

金属热处理 术语

声明 本文是学习GB-T 7232-2023 金属热处理 术语. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本文件界定了金属热处理基础、热处理工艺、组织与性能和热处理装备的主要术语及其定义。 本文件适用于金属热处理相关技术标准及技术文件。 …

vscode 代码片段,快捷注释

一、Ctrl shift p 输入 snippets 配置代码片段 二、可以新建全局片段&#xff0c; 也可以配置现有的。 三、插入代码片段配置 { // api: 提供给第三方使用的接口 // author: 标明作者 // param: 参数 // return: 返回值 // todo: 待办 // version: 版本号 // inheritdoc: …

线性代数与编程语言结合 基础

什么是线性代数 线性代数是数学的一个分支&#xff0c;研究向量空间和线性变换的理论与方法。它涉及了向量、矩阵、线性方程组、线性映射等概念与运算规则。线性代数在科学和工程领域中被广泛应用&#xff0c;如物理学、计算机图形学、统计学、电子工程等。它提供了一种强大的…

艾奇软件怎么下载安装?

艾奇视频电子相册制作软件是免费的电子相册制作软件&#xff0c;照片配上音乐加上炫酷的过渡效果点缀图片和文字说明&#xff0c;轻松制作成各种视频格式的电子相册。 现在很多人尝试制作电子相册来记录美好瞬间&#xff0c;不论是婚礼邀请函&#xff0c;商业宣传&#xff0c;…

SpringCloud——微服务

微服务技术栈 在之前的开发过程中&#xff0c;我们将所有的服务都部署在一台服务器中&#xff0c;当我们的服务开始越来越多&#xff0c;业务越来越复杂&#xff0c;当一台服务器不能承担我们的业务的时候&#xff0c;就需要将不同的业务分开部署在不同的服务器上&#xff0c;…

leetcode725. 分隔链表(java)

分隔链表 题目描述拆分链表代码演示 题目描述 给你一个头结点为 head 的单链表和一个整数 k &#xff0c;请你设计一个算法将链表分隔为 k 个连续的部分。 每部分的长度应该尽可能的相等&#xff1a;任意两部分的长度差距不能超过 1 。这可能会导致有些部分为 null 。 这 k 个部…

C【操作符】

1. 操作符分类&#xff1a; 2. 算术操作符 int main() {double a 5 % 2;//商2余1printf("a %lf\n", a);return 0; } 3. 移位操作符 3.1 左移操作符 左边抛弃、右边补0 3.2 右移操作符 首先右移运算分两种&#xff1a; 1. 逻辑移位 左边用0填充&#xff0c;右边丢…

5.4 转换数据

5.4 转换数据 5.4.1 哑变量处理类别型数据5.4.2 离散化连续型数据1、等宽法2、等频法3、聚类分析法 数据集 E:/Input/ptest.csv 5.4.1 哑变量处理类别型数据 数据分析模型中有相当一部分的算法模型都要求输入的特征为数值型&#xff0c;但实际数据中特征的类型不一定只有数值…

【C++基于多设计模式下的同步异步日志系统】

文章目录 [toc] 1 :peach:项目介绍:peach:2 :peach:开发环境:peach:3 :peach:核心技术:peach:4 :peach:环境搭建:peach:5 :peach:日志系统介绍:peach:5.1 :apple:为什么需要日志系统&#xff1f;:apple:5.2 :apple:日志系统技术实现:apple:5.2.1 :lemon:同步写日志:lemon:5.2.2…

如何在公网远程访问内网的jupyter notebook,随时随地都能跑代码!

文章目录 前言1. Python环境安装2. Jupyter 安装3. 启动Jupyter Notebook4. 远程访问4.1 安装配置cpolar内网穿透4.2 创建隧道映射本地端口 5. 固定公网地址 前言 Jupyter Notebook&#xff0c;它是一个交互式的数据科学和计算环境&#xff0c;支持多种编程语言&#xff0c;如…

Ruoyi-vue项目讲解

[TOC]若依前后端调用接口解读 若依github官方下载地址 若依gitee官方下载地址 1.验证码时候的前端调用接口 调用前端登录界面的时候&#xff0c;调用的是login.vue这个文件中的created函数 这里我们查看getCode函数方法 可以看到&#xff0c;这里先调用了一个getCodeImg函数…

ChatGLM Pytorch从0编写Transformer算法

预备工作 # !pip install http://download.pytorch.org/whl/cu80/torch-0.3.0.post4-cp36-cp36m-linux_x86_64.whl numpy matplotlib spacy torchtext seaborn import numpy as np import torch import torch.nn as nn import torch.nn.functional as F import math, copy, tim…

八股整理(计网,os)

1.进程和线程的区别 1.1什么是进程和线程 1.进程是操作系统进行资源分配和调度的一个基本单位&#xff0c;资源包括cpu&#xff0c;内存&#xff0c;磁盘等等IO设备等等。每一个进程启动都会最先产生一个线程&#xff0c;即主线程&#xff0c;然后主线程会在创建其他的子线程…

深入理解WPF中MVVM的设计思想

近些年来&#xff0c;随着WPF在生产&#xff0c;制造&#xff0c;工业控制等领域应用越来越广发&#xff0c;很多企业对WPF开发的需求也逐渐增多&#xff0c;使得很多人看到潜在机会&#xff0c;不断从Web&#xff0c;WinForm开发转向了WPF开发&#xff0c;但是WPF开发也有很多…

【Redis缓存:常见问题及解决方案】

目录 ①缓存雪崩 常见的解决方案 加锁排队 随机化过期时间 设置⼆级缓存 ②缓存穿透 常见的解决方案 布隆过滤器 缓存空结果 接口层增加校验 ③缓存击穿 常见的解决方案 加锁排队 设置热点数据永远不过期 分布式缓存系统 ④缓存预热 缓存预热的实现思路 ①缓…

C语言开发手册,辅助工具

方便查函数,头文件,日常语法,c99与c11的差异,等 https://www.php.cn/manual/view/34866.html

微信小程序通过普通二维码扫码进入指定页面带参数

微信小程序通过普通二维码扫码进入指定页面带参数 首先进入公众号开发者后台 https://mp.weixin.qq.com/ 进入开发管理->开发设置 扫普通链接二维码打开小程序 二维码规则填写服务器域名、填写前缀占用规则不占用就是其他开发者都可以使用这个后缀&#xff0c;占用则只能…

MYSQL性能优化——基于成本的优化

MYSQL性能优化 详见 GitBook MYSQL性能优化 什么是成本 我们之前老说MySQL执行一个查询可以有不同的执行方案&#xff0c;它会选择其中成本最低&#xff0c;或者说代价最低的那种方案去真正的执行查询。不过我们之前对成本的描述是非常模糊的&#xff0c;其实在MySQL中一条查…

【计算思维题】少儿编程 蓝桥杯青少组计算思维 数学逻辑思维真题详细解析第10套

少儿编程 蓝桥杯青少组计算思维题真题及解析第10套 1、明明买了一个扫地机器人,可以通过以下指令控制机器人运动: F:向前走 10 个单位长度 L:原地左转 90 度 R:原地右转 90 度 机器人初始方向向右,需要按顺序执行以下那条指令,才能打扫完下图中的道路 A、F-L-F-R-F-F-R-F-…

北邮22级信通院数电:Verilog-FPGA(3)实验“跑通第一个例程”modelsim仿真及遇到的问题汇总(持续更新中)

北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章&#xff0c;请访问专栏&#xff1a; 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客 注意&#xff1a;本篇文章所有绝对路径的展示都来自…