Vue与React 登录权限全局拦截对比
无论是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>,
相关文章
- MyBatis如何实现分页查询?_mybatis collection分页查询
- 通过Mybatis Plus实现代码生成器,常见接口实现讲解
- MyBatis-Plus 日常使用指南_mybatis-plus用法
- 聊聊:Mybatis-Plus 新增获取自增列id,这一次帮你总结好
- MyBatis-Plus码之重器 lambda 表达式使用指南,开发效率瞬间提升80%
- Spring Boot整合MybatisPlus和Druid
- mybatis 代码生成插件free-idea-mybatis、mybatisX
- mybatis-plus 团队新作 mybatis-mate 轻松搞定企业级数据处理
- Maven 依赖范围(scope) 和 可选依赖(optional)
- Trace Sql:打通全链路日志最后一里路