完整版:https://www.cnblogs.com/yangyangxxb/p/10066650.html
12、react路由守卫?
a、在之前的版本中,React Router 也提供了类似的 onEnter
钩子,但在 React Router 4.0 版本中,取消了这个方法。
b、那么在react中如果我们也需要路由守卫怎么办?比如在跳转路由前需要判断用户是否登录?如果登录才可以进行跳转,否则没有权限
c、
//下面是我的实现方式, //首先,准备一份路由表, //包含了路由的地址,组件以及是否需要权限校验: import { HomePage } from '../pages/home/home.page'; import { LoginPage } from '../pages/login/login.page'; import { ErrorPage } from '../pages/error/error.page'; interface routerConfigModel { path:string, component?:any, auth?:boolean } export const routerConfig:routerConfigModel[] = [ { path:'/', component:HomePage, auth:true, }, { path:'/home', component:HomePage, auth:true, }, { path:'/login', component:LoginPage, }, { path:'/404', component:ErrorPage } ]; //将 auth 设置为 true,表示该路由需要权限校验。 //然后,定义 Router 组件,该组件是经过高阶组件包装后的结果: import * as React from 'react'; import { HashRouter,Switch } from 'react-router-dom'; import { FrontendAuth } from '../components/frontend-auth/frontend-auth.component' import { routerConfig } from './router.config' export class Router extends React.Component{ render(){ return( <HashRouter> <Switch> <FrontendAuth config={routerConfig} /> </Switch> </HashRouter> ); } } //所有的路由跳转,都交给 FrontendAuth 高阶组件代理完成。 //下面是 FrontendAuth 组件的实现: import * as React from 'react'; import { Route,Redirect } from 'react-router-dom'; import { propsModel } from './frontend-auth.model' export class FrontendAuth extends React.Component<any,propsModel>{ render(){ const { location,config } = this.props; const { pathname } = location; const isLogin = localStorage.getItem('__config_center_token') // 如果该路由不用进行权限校验,登录状态下登陆页除外 // 因为登陆后,无法跳转到登陆页 // 这部分代码,是为了在非登陆状态下,访问不需要权限校验的路由 const targetRouterConfig = config.find((v:any) => v.path === pathname); if(targetRouterConfig && !targetRouterConfig.auth && !isLogin){ const { component } = targetRouterConfig; return <Route exact path={pathname} component={component} /> } if(isLogin){ // 如果是登陆状态,想要跳转到登陆,重定向到主页 if(pathname === '/login'){ return <Redirect to='/' /> }else{ // 如果路由合法,就跳转到相应的路由 if(targetRouterConfig){ return <Route path={pathname} component={targetRouterConfig.component} /> }else{ // 如果路由不合法,重定向到 404 页面 return <Redirect to='/404' /> } } }else{ // 非登陆状态下,当路由合法时且需要权限校验时,跳转到登陆页面,要求登陆 if(targetRouterConfig && targetRouterConfig.auth){ return <Redirect to='/login' /> }else{ // 非登陆状态下,路由不合法时,重定向至 404 return <Redirect to='/404' /> } } } } //以及对应的 Model: export interface propsModel { config:any[], } //页面上的路由跳转,都由 FrontendAuth 高阶组件代理了, //在 Switch 组件内部,不再是 Route 组件, //而只有一个 FrontendAuth 组件。 //FrontendAuth 组件接收一个名为 config 的 Props,这是一份路由表。 //同时,由于 FrontendAuth 组件放在了 Switch 组件内部,React Router 还自动为 FrontendAuth 注入了 location 属性, //当地址栏的路由发生变化时,就会触发 location 属性对象上的 pathname 属性发生变化, //从而触发 FrontendAuth 的更新(调用 render 函数)。 //FrontendAuth 的 render 函数中, //根据 pathname 查找到路由表中的相关配置, //如果该配置中指定了无需校验,就直接返回相应的 Route 组件。 //如果查找到的配置需要进行校验,再根据是否登陆进行处理,具体可以查看代码中的注释。 总结一下,实现路由守卫需要考虑到以下的问题: 未登录情况下,访问不需要权限校验的合法页面:允许访问 登陆情况下,访问登陆页面:禁止访问,跳转至主页 登陆情况下,访问除登陆页以外的合法页面:允许访问 登陆情况下,访问所有的非法页面:禁止访问,跳转至 404 未登录情况下,访问需要权限校验的页面:禁止访问,跳转至登陆页 未登录情况下,访问所有的非法页面:禁止访问,跳转至 404