网站首页 > 技术文章 正文
无论是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-08-05 智能图书馆管理系统开发实战系列(二):高保真原型设计
- 2025-08-05 Next.js 14 Server Actions:告别API路由的全栈开发新范式
- 2025-08-05 我如何驯服 Cursor AI,让它每次都生成正确代码
- 2025-08-05 React中实现苹果的Liquid Glass新拟态UI
- 2025-08-05 前端大一统时代来了
- 2025-08-05 基于 Rust 和 React 新一代全栈 Web 框架 Tuono 强势来袭!
- 2025-08-05 AI 编程的三步走:从“能用”到“能优化”
- 2025-08-05 从Rax+DX到React,一次跨端组件重写的AI提效探索
- 2025-08-05 三行代码让 React 全面拥抱 MCP,开发者效率要起飞了?
- 2025-05-22 如何通过 OpenMemory MCP 让你的客户端更具上下文感知能力
- 08-06中等生如何学好初二数学函数篇
- 08-06C#构造函数
- 08-06初中数学:一次函数学习要点和方法
- 08-06仓颉编程语言基础-数据类型—结构类型
- 08-06C++实现委托机制
- 08-06初中VS高中三角函数:从"固定镜头"到"360°全景",数学视野升级
- 08-06一文讲透PLC中Static和Temp变量的区别
- 08-06类三剑客:一招修改所有对象!类方法与静态方法的核心区别!
- 最近发表
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (84)
- 标签用于 (71)
- 主键只能有一个吗 (77)
- c#console.writeline不显示 (95)
- pythoncase语句 (88)
- es6includes (74)
- sqlset (76)
- windowsscripthost (69)
- apt-getinstall-y (100)
- node_modules怎么生成 (87)
- chromepost (71)
- flexdirection (73)
- c++int转char (80)
- mysqlany_value (79)
- static函数和普通函数 (84)
- el-date-picker开始日期早于结束日期 (70)
- asynccallback (71)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)