React路由守卫
前言
React不同于vue,它没有路由守卫,所以要想实现路由跳转的权限设置就需要自己写了。本文参考了以下这篇文章:(juejin.cn/post/719557…)
路由配置
在router文件夹下新建两个文件,如下图所示:
index.jsx存放路由数组:注意,存放数组即可,不需要用BrowserRouter进行包裹。
import Home from "@/pages/Home"
import Data from "@/pages/Data"
import User from "@/pages/User"
import Login from "@/pages/Login"
import Detail from "@/pages/Detail"
import UserInfo from "@/pages/UserInfo"
import Account from "@/pages/Account"
import About from "@/pages/About"
const router = [
{
path: "/",
element: <Home />,
auth: true,
},
{
path: "/data",
element: <Data />,
auth: true,
},
{
path: "/user",
element: <User />,
auth: true,
},
{
path: "/login",
element: <Login />,
auth: false,
},
{
path: "/detail",
element: <Detail />,
auth: true,
},
{
path: "/userinfo",
element: <UserInfo />,
auth: true,
},
{
path: "/account",
element: <Account />,
auth: true,
},
{
path: "/about",
element: <About />,
auth: true,
},
]
export default router
AuthRoute.jsx存放路由权限控制:
import { Toast } from "antd-mobile"
import { useEffect } from "react"
import { matchRoutes, useNavigate } from "react-router-dom"
import router from "./index.jsx"
const AuthRoute = ({ children, auth }) => {
const navigate = useNavigate()
const token = localStorage.getItem("token") || ""
const mathchs = matchRoutes(router, location)
const isExist = mathchs?.some((item) => item.pathname == location.pathname)
useEffect(() => {
if (token == "" && auth) {
Toast.show("token 过期,请重新登录!")
navigate("/login")
}
// 这里判断条件是:token 存在并且是匹配到路由并且是已经登录的状态
if (token && isExist) {
// 如果你已经登录了,但是你通过浏览器里直接访问login的话不允许直接跳转到login路由,必须通过logout来控制退出登录或者是token过期返回登录界面
if (location.pathname == "/" || location.pathname == "/login") {
navigate("/")
} else {
// 如果是其他路由就跳到其他的路由
navigate(location.pathname)
}
}
}, [token, location.pathname])
return children
}
export default AuthRoute
最后,在App.jsx中出路路由渲染:
import { Route, Routes } from "react-router-dom"
import NavBar from "./components/NavBar"
import "./App.less"
import AuthRoute from "./router/AuthRoute"
import router from "./router"
function App() {
// 处理我们的routers 类似于vue中的路由守卫
const RouteAuthFun = (routeList) => {
return routeList.map((item) => {
return (
<Route
path={item.path}
element={
<AuthRoute auth={item.auth} key={item.path}>
{item.element}
</AuthRoute>
}
key={item.path}
>
{/* 递归调用,因为可能存在多级的路由 */}
{item?.children && RouteAuthFun(item.children)}
</Route>
)
})
}
return (
<div className="app">
<div className="body">
{/* 带有路由守卫的写法 */}
<Routes>{RouteAuthFun(router)}</Routes>
</div>
<div className="bottom">
<NavBar />
</div>
</div>
)
}
export default App
这样就可以实现路由跳转的权限控制啦~