网站首页 > 技术文章 正文
无论是vue还是react全局登录权限的拦截在业务逻辑上都需要实现两处:
- 对调用后台api接口返回结果进行拦截.如果返回401状态,或者特定结果就说需要需要登录.这块代码都相同.
- 对路由进行拦截. 这里vue和react实现的方式各有不同.
vue路由如何进行拦截
vue比较简单,直接用全局路由守卫就可以实现.
router.beforeEach((to,from, next) => {
//判读有没有登录,或者当前页面是不是登录页面,做相应的处理.
if(store.state.userInfo || to.path === "/login"){
next()
} else {
next({
path: "/login"
})
}
)
react路由如何进行拦截
1. 高阶组件的编写
import React from 'react'
import { Route, Redirect } from 'react-router-dom'
import { message } from 'antd'
export default function AuthRoute({ component: Component, ...rest }) {
return (
<Route {...rest} render={(props) => {
const sid = !!sessionStorage.getItem('sid')
if (!sid) {
message.error('请先登录!')
return (
<Redirect to={{
pathname: '/',
state: {
from: props.location
}
}} />
)
} else {
return <Component {...props} />
}
}}></Route>
)
使用:
import React, { Component } from 'react'
import { Route, Switch, Redirect } from 'react-router-dom'
import AuthRoute from './components/AuthRoute'
import loginfrom './pages/login'
import cloudviewfrom './pages/cloudview'
import Home from './pages/Home'
export default class App extends Component {
render() {
return (
<div style = {{height:'100%'}}>
{/* 一级路由注册 */}
<Switch>
<Route exact path='/' render={() => <Redirect to='/login'/>}></Route>
<Route path='/login' component={Login}></Route>
<AuthRoute path='/cloudview' component={CloudView}></AuthRoute>
<AuthRoute path='/home' component={Home}></AuthRoute>
</Switch>
</div>
)
}
2.自定义跳转hook,实现路由守卫RouterBeforeEach
官方提供的路由跳转是使用useNavigate hook的,这里我们要实现路由守卫,那么我需要在路由跳转前做逻辑的判断,所以我自定义了一个useUtilsNavigate hook用于跳转前的判断。只要是通过这个hook跳转的路由都可以响应到路由守卫。
import { NavigateFunction, Location, To, NavigateOptions } from "react-router-dom";
import { RouterLoader } from "@/routes/route";
type IrouterBeforeLoad = (to:Ito,location?: Location) => Boolean;
interface Ito {
to: To, options?: NavigateOptions
}
let routerBeforeLoad: IrouterBeforeLoad;
let flag: Boolean = true;
const RouterBeforeEach = (fun: IrouterBeforeLoad) => {
///页面刷新时,配合loader实现调用,并做拦截重定向,由flag判断是否是初次刷新页面,以免在useUtilsNavigate调用是触发多次路由校验
RouterLoader((res: any,redirectUrl:string) => {
let result: Boolean=true;
if (flag) {
let url = new URL(res.request.url)
result = fun({ to: url.pathname })
if (redirectUrl==url.pathname) {
result = true;
}
}
return result;
})
routerBeforeLoad = fun;
}
///所有的js路由跳转通过此函数,由此做路由拦截
const useUtilsNavigate=(navigate:NavigateFunction,location:Location,to: To, options?: NavigateOptions)=>{
if (routerBeforeLoad && routerBeforeLoad({ to, options }, location)) {
//flag设置false标志已经不是第一次加载页面
flag = false;
navigate(to, options)
} else {
return;
}
//flag设置false标志已经不是第一次加载页面
flag = false;
navigate(to,options)
}
export { useUtilsNavigate, RouterBeforeEach };
export type { IrouterBeforeLoad,Ito };
RouterLoader这个函数钩子是在路由定义的文件里面导出的,可以看到在route.tsx,其在loader属性里面被调用。loader这个也是新版本提供的一个新功能,其会在组件页面加载时先回调这个钩子,我在这里根据flag判断是否页面初始加载。因为页面通过URL直接打开的话,是没有经过useUtilsNavigate,也就是无法通过它去做路由监听,所以需要使用loader这个钩子,在初次加载时,触发路由守卫。
在程序主入口注册路由守卫钩子
import ReactDOM from 'react-dom';
import {RouterProvider } from "react-router-dom";
import './index.css'
import { Router } from './routes/route';
import { AliveScope } from 'react-activation'
import React from 'react';
import { RouterBeforeEach } from "@/utils/useUtilsNavigate";
RouterBeforeEach(( to,from) => {
console.log("路由守卫to", to)
console.log("路由守卫from", from)
return true;
})
ReactDOM.render(
<AliveScope>
<RouterProvider router={Router()}/>
</AliveScope>,
猜你喜欢
- 2025-05-22 如何通过 OpenMemory MCP 让你的客户端更具上下文感知能力
- 2025-05-22 你在 Next.js 中用错 "use client" 了吗?
- 2025-05-22 expo开发RN前,先看完这篇文章节省你的对里面Router的理解
- 2025-05-22 深入理解受控组件、非受控组件
- 2025-05-22 深入解读新一代全栈框架 Fresh
- 2025-05-22 前端搭建 MCP Client(Web版)+ Server + Agent 实践
- 2025-05-22 写一句话,GPT 帮我生成整个项目?实测爆火开源工具 gpt-engineer
- 2025-05-22 MasterGo + MCP,借助 AI 实现设计稿转代码
- 2025-05-22 如何实现一个Claude Artifacts类似的代码生成工具?
- 2025-05-22 如何让 AI 理解你的项目结构?| Cursor 高阶使用技巧
- 最近发表
- 标签列表
-
- cmd/c (64)
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- sqlset (64)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- chromepost (65)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- js数组插入 (83)
- linux删除一个文件夹 (65)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)