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


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

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

    • 路由组件 - ExRouter.tsx

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

      ```js // 基于 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 && } > ) }

      export default Component ```

    • 路由拦截(路由守卫)组件:

      ```js // 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 // } else if (!location.pathname.includes('/login') && !token) { // // 不是跳转登录页 && token无值 // return // } // 验证通过 return props.children }

      export default Component ```

    • 上面两个组件在路由中的使用:

      ```js 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 ( }> ) }

      // 基础路由 const baseRoutes: Record [] = [ { 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 [] = [ ...baseRoutes, { path: "/404", element: (<>页面地址不存在>), }, { path: "/", element: }, { path: "*", element: }, ]

      // 加载配置式路由 function Router () { return ( {/* 加载所有路由 /} {/ { useRoutes(props.routes) } /} {/ 加载所有路由,并扩展路由配置 */} ) }

      // 导出 export default Router ```

      test.gif

  • 相关阅读:
    设计模式——4. 建造者模式
    【沐风老师】怎么在3DMAX中使用MAXScript脚本动画编程?
    基于Linux centos7部署 Sonic(简版)
    盘盘在项目中你常用的那些数组API
    A Frustratingly Easy Approach for Entity and Relation Extraction 论文阅读
    事件修饰符
    Linux | 详解 diff 命令的使用方法
    redis 哨兵
    【学习笔记】深度学习入门:基于Python的理论与实现-误差反向传播法
    Linux基础学习笔记(十二)——管道命令
  • 原文地址:https://blog.csdn.net/zz00008888/article/details/132974424