1. 程式人生 > >react router @4 和 vue路由 詳解(七)react路由守衛

react router @4 和 vue路由 詳解(七)react路由守衛

完整版: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