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
    
相關文章
相關標籤/搜索