定义路由表
import {BrowserRouter, Route, RouteObject, Routes,} from "react-router-dom";
import {Home, Login, NotFound} from "@/views";
import {RouterGuard} from "@/routers/router_guard.tsx";
import {ReactNode} from "react";
import {Test} from "@/views/test/test.tsx";
import {LOGIN_PATH} from "@/utils/constant";
import {Broken} from "@/views/Broken/broken.tsx";type AuthRouteObject = {needAuth?: boolean
}const router: RouteObject[] & AuthRouteObject[] = [{path: "/",element: <Home></Home>,needAuth: true,children:[{path: "/test",element: <Test/>,}]},{path: LOGIN_PATH,element: <Login></Login>,needAuth:true},{path:"/500",element:<Broken></Broken>},{path: "*",element: <NotFound></NotFound>}
]export const RenderRouters = () => {const traverseRoutes = (router: RouteObject[] & AuthRouteObject[]) => {return router.map((route: RouteObject & AuthRouteObject): ReactNode => {const element = <RouterGuard needAuth={route?.needAuth} element={route.element}/>if(Array.isArray(route.children) && route.children.length>0){return (<Route path={route.path} element={element} key={route.path}>{traverseRoutes(route.children)}</Route>)}return <Route path={route.path} element={element} key={route.path}/>})}return (<><BrowserRouter><Routes>{traverseRoutes(router)}</Routes></BrowserRouter></>)
}
定义守卫组件
import {PropsWithChildren, ReactNode} from "react";
import {useUserStore} from "@/store/user_store";
import {Navigate, useLocation} from "react-router-dom";
import {LOGIN_PATH} from "@/utils/constant";interface Props extends PropsWithChildren {element: JSX.Element | ReactNodeneedAuth?:boolean
}export const RouterGuard = (props: Props): JSX.Element | React.ReactNode => {const userStore = useUserStore()const pathName = useLocation().pathnameconst token = userStore.tokenif (!props.needAuth){return props.element}if (token && pathName == LOGIN_PATH){return <Navigate to="/" replace></Navigate>}if (!token && pathName !== LOGIN_PATH) {return <Navigate to={LOGIN_PATH} replace></Navigate>}return props.element
}
使用
import './App.css'
import {RenderRouters} from "@/routers/router.tsx";function App() {return (<><RenderRouters></RenderRouters></>)
}export default App
效果展示