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, 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

6f40a4ef0dd46ab9cde5069f77de27c9_1a5345cbd3ed6cfec9b1c11289622ffc.gif


相关文章
|
2月前
|
编解码 前端开发 JavaScript
js react antd 实现页面低分变率和高分变率下字体大小自适用,主要是配置antd
在React中结合Ant Design与媒体查询,通过less变量和响应式断点动态调整`@font-size-base`,实现多分辨率下字体自适应,提升跨设备体验。
102 2
|
4月前
|
JavaScript 前端开发 API
对比Vue框架与React库的主要区别
在选择Vue还是React时,考虑项目的需求、团队的熟悉程度和个人偏好至关重要。如果项目需要快速原型开发和较小的学习曲线,Vue可能是更好的选择。相反,如果项目需要更大的灵活性,或者项目团队已经有React的经验,那么React可能是更合适的选择。
222 13
|
7月前
|
移动开发 前端开发 JavaScript
Vue与React两大前端框架的主要差异点
以上就是Vue和React的主要差异点,希望对你有所帮助。在选择使用哪一个框架时,需要根据项目的具体需求和团队的技术栈来决定。
437 83
|
8月前
|
前端开发
如何在React Router中进行嵌套路由配置?
如何在React Router中进行嵌套路由配置?
417 57
|
8月前
|
JavaScript 前端开发 算法
vue和react 哪个更强大
vue和react 哪个更强大
229 3
|
12月前
|
存储 缓存 JavaScript
如何优化React或Vue应用的性能
需要注意的是,性能优化是一个持续的过程,需要根据具体的应用场景和性能问题进行针对性的优化。同时,不同的项目和团队可能有不同的优化重点和方法,要结合实际情况灵活运用这些优化策略,以达到最佳的性能效果。
394 61
|
12月前
|
JavaScript 前端开发 测试技术
React和Vue的性能对比如何?
需要注意的是,性能不仅仅取决于框架本身,还与开发者的代码质量、架构设计以及项目的优化程度等密切相关。因此,在评估性能时,应该综合考虑多个因素,而不是仅仅局限于框架之间的比较。
638 58
|
12月前
|
JavaScript 前端开发 开发者
React和Vue有什么区别?
React 和 Vue 都有各自的优势和特点,开发者可以根据项目的需求、团队的技术背景以及个人的喜好来选择使用。无论是 React 还是 Vue,它们都在不断发展和完善,为前端开发提供了强大的支持。
1065 58
|
12月前
|
监控 JavaScript 前端开发
如何在实际应用中测试和比较React和Vue的性能?
总之,通过多种方法的综合运用,可以相对客观地比较 React 和 Vue 在实际应用中的性能表现,为项目的选择和优化提供有力的依据。
303 1
|
12月前
|
JavaScript 前端开发 开发者
JavaScript框架React vs. Vue:一场性能与易用性的较量
JavaScript框架React vs. Vue:一场性能与易用性的较量
306 0