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

简介: React 像 vue 一样配置页面路由,并支持重定向路由,路由守卫等(使用 useRoutes 完成)
  • 希望达到跟 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, RouteObject, IndexRouteObject, NonIndexRouteObject } from 'react-router-dom'
import { useLocation, Location } from 'react-router'
/**
 * @description: 扩展属性
 */
interface ExRouteObjectProps {
  /**
   * @description: 重定向路由地址
   */
  redirect?: string,
  /**
   * @description: 子列表
   */  
  children?: ExRouteObject[]
}
/**
 * @description: 扩展 IndexRouteObject
 */
export interface ExIndexRouteObject extends Omit<IndexRouteObject, 'children'>, ExRouteObjectProps {
}
/**
 * @description: 扩展 NonIndexRouteObject
 */
export interface ExNonIndexRouteObject extends Omit<NonIndexRouteObject, 'children'>, ExRouteObjectProps {
}
/**
 * @description: 路由对象类型
 */
export type ExRouteObject = ExIndexRouteObject | ExNonIndexRouteObject
/**
 * @description: 找到路由对象类型
 */
type ExRouteObjectFind = ExRouteObject | undefined
/**
 * @description: 组件参数
 */
export interface ExRouterProps {
  /**
   * @description: 路由列表
   */
  routes: ExRouteObject[]
}
const Component = (props: ExRouterProps) => {
  // 当前导航对象
  const location = useLocation()
  // 找到路由对象
  const findRoute = (routes: ExRouteObject[], location: Location): ExRouteObjectFind => {
    // 当前层级检查一轮
    let route: any = routes.find((item: any) => item.path === location.pathname)
    // 没有则搜索当前层级同级子页面
    if (!route) {
      // 排查,找到停止
      routes.some((item: any) => {
        // 取出子列表
        const children: ExRouteObject[] = item?.children || []
        // 子列表有值
        if (children.length) {
          // 进行排查
          route = findRoute(children, location) 
        }
        // 有值则暂停
        return !!route
      })
    }
    // 返回
    return route
  }
  // 找到当前路由
  const route: ExRouteObjectFind = findRoute(props.routes, location)
  // 返回渲染
  return (
    <>
      {/* 加载所有路由 */}
      { useRoutes(props.routes as RouteObject[]) }
      {/* 检查当前路由是否需要重定向 */}
      { 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 { ExRouteObject } from './ExRouter'
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>
  )
}
// 菜单路由
export const menuRoutes: ExRouteObject[] = [
  {
    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>[] = [
  ...menuRoutes,
  {
    path: '/home',
    element: lazyload('views/home'),
  },
  {
    path: '/user',
    element: lazyload('views/user'),
  },
  {
    path: "/404",
    element: (<>页面地址不存在</>),
  },
  { path: "/", element: <Navigate to="/home" /> },
  { path: "*", element: <Navigate to="/404" /> },
]
// 加载配置式路由
function Router () {
  return (
    <BeforeEach>
      <ExRouter routes={routes}></ExRouter>
    </BeforeEach>
  )
}
// 导出
export default Router
相关文章
|
8天前
|
JavaScript 前端开发
如何在 Vue 项目中配置 Tree Shaking?
通过以上针对 Webpack 或 Rollup 的配置方法,就可以在 Vue 项目中有效地启用 Tree Shaking,从而优化项目的打包体积,提高项目的性能和加载速度。在实际配置过程中,需要根据项目的具体情况和需求,对配置进行适当的调整和优化。
|
1月前
|
JavaScript 数据可视化
vue-cli学习二:vue-cli3版本 创建vue项目后,Runtime-Compiler和Runtime-only两个模式详解;vue项目管理器;配置文件的配置在哪,以及如何配置
这篇文章详细介绍了Vue CLI 3版本创建项目时的Runtime-Compiler和Runtime-only两种模式的区别、Vue程序的运行过程、render函数的使用、eslint的关闭方法,以及Vue CLI 2和3版本配置文件的不同和脚手架3版本创建项目的配置文件配置方法。
40 3
vue-cli学习二:vue-cli3版本 创建vue项目后,Runtime-Compiler和Runtime-only两个模式详解;vue项目管理器;配置文件的配置在哪,以及如何配置
|
20天前
|
JavaScript 前端开发 开发者
如何在 Visual Studio Code (VSCode) 中使用 ESLint 和 Prettier 检查代码规范并自动格式化 Vue.js 代码,包括安装插件、配置 ESLint 和 Prettier 以及 VSCode 设置的具体步骤
随着前端开发技术的快速发展,代码规范和格式化工具变得尤为重要。本文介绍了如何在 Visual Studio Code (VSCode) 中使用 ESLint 和 Prettier 检查代码规范并自动格式化 Vue.js 代码,包括安装插件、配置 ESLint 和 Prettier 以及 VSCode 设置的具体步骤。通过这些工具,可以显著提升编码效率和代码质量。
186 4
|
24天前
|
资源调度 JavaScript 前端开发
路由管理:Vue Router的使用和配置技巧
【10月更文挑战第21天】路由管理:Vue Router的使用和配置技巧
30 3
|
1月前
|
JavaScript API
vue 批量自动引入并注册组件或路由等等
【10月更文挑战第12天】 vue 批量自动引入并注册组件或路由等等
|
1月前
|
存储 前端开发 中间件
vue3之vite配置vite-plugin-mock使用mock轻松创建模拟数据提高开发效率
vue3之vite配置vite-plugin-mock使用mock轻松创建模拟数据提高开发效率
247 0
|
1月前
|
JavaScript 前端开发 API
vue3中常用插件的使用方法:按需引入自定义组件,自动导入依赖包,自动生成路由,自动生成模拟数据
vue3中常用插件的使用方法:按需引入自定义组件,自动导入依赖包,自动生成路由,自动生成模拟数据
582 0
|
1月前
|
JavaScript 前端开发 UED
vue中vue-router路由懒加载(按需加载)的作用以及常见的实现方法
vue中vue-router路由懒加载(按需加载)的作用以及常见的实现方法
170 1
|
1月前
|
JavaScript 前端开发 UED
|
1月前
|
JavaScript 前端开发 API
前端技术分享:Vue.js 动态路由与守卫
【10月更文挑战第1天】前端技术分享:Vue.js 动态路由与守卫