react router @4 和 vue路由 详解(七)react路由守卫

完整版:http://www.javashuo.com/article/p-rfhkumuv-be.htmlhtml

 

十二、react路由守卫?react

  a、在以前的版本中,React Router 也提供了相似的 onEnter 钩子,但在 React Router 4.0 版本中,取消了这个方法。react-router

  b、那么在react中若是咱们也须要路由守卫怎么办?好比在跳转路由前须要判断用户是否登陆?若是登陆才能够进行跳转,不然没有权限frontend

  c、dom

复制代码
//下面是个人实现方式,
//首先,准备一份路由表,
//包含了路由的地址,组件以及是否须要权限校验:

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
    
相关文章
相关标签/搜索