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