-
React 路由菜单学习 渲染
-
感谢 @秋天不落叶 博主 提供的开源模版
-
针对项目中 使用的部分方法构建react-router;
一、初级router-配置 单router配置版本
主要学习 动态路由配置部分 以及 路由拦截器的使用方式
main.tsx中
import React from "react"
import { createRoot } from "react-dom/client"
import App from "./App"
import { BrowserRouter } from "react-router-dom"
const root = document.getElementById("root")
if (root) {
createRoot(root).render(
<React.StrictMode>
<BrowserRouter> // 这里还有个HashRouter 区别是# BrowserRouter不带#
<App />
</BrowserRouter>
</React.StrictMode>
)
}
App.jsx中
import * as React from "react"
import { Routes, Route } from "react-router-dom"
import Layout from "./Layout/index"
import Dashboard from "./views/dashboard/index"
import Login from "./views/login/index"
import NoMatch from "./views/noMatch/index"
export default function App() {
return (
<div>
{/* 要注册的路由必须有Routes 包裹 */}
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Dashboard />} />
{/*
index :表示当前匹配的路由
path:路由路径
element:展示的组件
*/}
<Route path="login" element={<Login />} />
<Route path="*" element={<NoMatch />} />
</Route>
</Routes>
</div>
)
}
二、hook 按模块封装 使用
import * as React from "react"
import Router from "./routes/index"
export default function App() {
return (
<div>
{/* 路由拦截器 包裹在Router组件前 */}
<AuthRouter>
<Router />
</AuthRouter>
{/* Loaing */}
</div>
)
}
src/routes/index.tsx 中
import React from "react"
import { Navigate } from "react-router-dom"
import { useRoutes } from "react-router-dom"
/* 路由页面 */
import Login from "@/views/login/index"
import Page404 from "@/views/errMessage/404"
import Page500 from "@/views/errMessage/500"
/* 子路由组 */
import Home from "./modules/home"
import Test from "./modules/test"
import Test2 from "./modules/test2"
export const RouteModule = [Home, Test, Test2]
/**
* 路由配置项
*
* path:'路径' // 路径,如果不是多级嵌套,可为 ' '
* hidden:true // 设置为true时不会出现在侧边栏
* name:'router-name' // 设定路由名,此项必填 (也是唯一标志名)
* element:<login /> // 组件
* alwaysShow: true // 设置该属性为true后,侧边栏就会出现多级嵌套,否则不会出现
* meta:{
* title:'title' // 设置该路由在侧边栏和面包屑的name
* icon:'svg-name' // 设置该路由的图标,对应路径 src/icons/svg
* }
*/
export const rootRouter = [
{
path: "/login",
element: <Login />,
meta: {
title: "登录页",
},
},
{
path: "/",
element: <Navigate to="/home" />,
},
...RouteModule,
{
path: "/404",
element: <Page404 />,
meta: {
title: "404页面",
},
},
{
path: "/500",
element: <Page500 />,
meta: {
title: "500页面",
},
},
{
path: "*",
element: <Navigate to="/404" />,
},
]
const Router = () => {
const routes = useRoutes(rootRouter)
return routes
}
export default Router
三、react中加入拦截器
加入拦截器
import React from 'react'
import { useLocation, Navigate } from 'react-router-dom'
import rootRouter from '@/routes'
import { getUserAPI } from '@/api/modules/user'
// mobx
import useStore from '@/store'
/**
* @description 递归查询对应的路由
* @param {String} path 当前访问地址
* @param {Array} routes 路由列表
* @returns array
*/
// // 设置白名单
const whitePaths = ['/login', '/404', '/500']
// 路由守卫配置函数
export const AuthRouter = (props: any) => {
const { pathname } = useLocation()
let {
useUserStore: { token, setUserInfo, userInfo },
} = useStore()
// 第一步 判断有无 token
if (token) {
// 第二步 判断是否前往login页面,等于跳转 '/', 不等于则继续判断
if (pathname === '/login') {
return <Navigate to="/" replace />
} else {
// 第三步 判断是否拿到用户个人信息及权限,没拿到则进行axios请求数据,进行信息存储及权限路由渲染,否则直接放行
if (Object.keys(userInfo).length < 1) {
// 获取用户个人信息 (此处使用 async await会报错)
getUserAPI()
.then((res) => {
setUserInfo(res.data as any)
})
.catch((err) => {})
// 合并路由
return props.children
} else {
return props.children
}
}
} else {
if (whitePaths.includes(pathname)) {
return props.children
} else {
return <Navigate to="/login" replace />
}
}
}