react路由守衛(wèi)的實(shí)現(xiàn)(路由攔截)
react不同于vue,通過在路由里設(shè)置meta元字符實(shí)現(xiàn)路由攔截。在使用 Vue ,框架提供了路由守衛(wèi)功能,用來在進(jìn)入某個(gè)路有前進(jìn)行一些校驗(yàn)工作,如果校驗(yàn)失敗,就跳轉(zhuǎn)到 404 或者登陸頁面,比如 Vue 中的 beforeEnter 函數(shù):
...
router.beforeEach(async(to, from, next) => {
const toPath = to.path;
const fromPath = from.path;
})
...
react實(shí)現(xiàn)路由攔截的基本思路還是利用Route 的render函數(shù)。通過判斷攔截條件來實(shí)現(xiàn)不同的組件的跳轉(zhuǎn),從而實(shí)現(xiàn)攔截。在之前的版本中,React Router 也提供了類似的 onEnter 鉤子,但在 React Router 4.0 版本中,取消了這個(gè)方法。React Router 4.0 以后采用了聲明式的組件,路由即組件,要實(shí)現(xiàn)路由守衛(wèi)功能,就得我們自己去寫了。
如果不使用路由守衛(wèi),Router 組件是這樣子的:
import * as React from 'react';
import { HashRouter,Switch,Route,Redirect } from 'react-router-dom';
import Index from "./page/index";
import Home from "./page/home";
import ErrorPage from "./page/error";
import Login from "./page/login";
export const Router = () => (
<HashRouter>
<Switch>
<Route path="/" exact component={Index}/>
<Route path="/login" exact component={Login}/>
<Route path="/home" exact component={Home}/>
<Route path="/404" exact component={ErrorPage}/>
<Redirect to="/404" />
</Switch>
</HashRouter>
);
上面的 Router 組件,包含了三個(gè)頁面:
登陸
主頁
404 頁面
以及四個(gè)路由:
根路由
登陸路由
主頁路由
404 路由
其中,根路由和 /home 路由,都定向到了主頁路由。
以上是一個(gè)基本的路由定義,可以在登陸/主頁和 404 頁面之間來回跳轉(zhuǎn),但也有一些問題:
非登陸狀態(tài)下,可以直接跳轉(zhuǎn)到主頁
登陸狀態(tài)下,也可以輸入 /login 路由跳轉(zhuǎn)到登錄頁
現(xiàn)在,我們想完成這樣的功能:
非登陸狀態(tài)下,無法直接跳轉(zhuǎn)到主頁,如果在非登陸狀態(tài)下進(jìn)行主頁跳轉(zhuǎn),需要重定向至登陸路由
登陸狀態(tài)下,無法跳轉(zhuǎn)至登錄頁,如果在登陸狀態(tài)下進(jìn)行登陸頁跳轉(zhuǎn),需要重定向至主頁路由
要完成這個(gè)功能,有兩種方案:
在每個(gè)組件中,根據(jù) props 上的 history 對(duì)象來進(jìn)行跳轉(zhuǎn)
進(jìn)行全局的路由守衛(wèi)處理
首先在跟目錄src下創(chuàng)建一個(gè)routerMap.js文件,代碼如下:
將 auth 設(shè)置為 true,表示該路由需要權(quán)限校驗(yàn)。
/**
* 定義路由組件,將 auth 設(shè)置為 true,表示該路由需要權(quán)限校驗(yàn)
*/
import Admin from "./pages/Admin";
import Login from "./pages/Login";
import Error from "./pages/Error";
export const routerMap = [
{path: "/", name: "admin", component: Admin, auth: true},
{path: "/login", name: "Login", component: Login},
{path: "/error", name: "error", component: Error},
];
所有的路由跳轉(zhuǎn),都交給 FrontendAuth 高階組件代理完成。下面是 FrontendAuth.js 組件的實(shí)現(xiàn):
/**
* 路由守衛(wèi)校驗(yàn)
*/
import React, {Component} from "react";
import {Route, Redirect} from "react-router-dom";
class FrontendAuth extends Component {
// eslint-disable-next-line no-useless-constructor
constructor(props) {
super(props);
}
render() {
const {routerConfig, location} = this.props;
const {pathname} = location;
const isLogin = localStorage.getItem("user");
console.log(pathname, isLogin);
console.log(location);
// 如果該路由不用進(jìn)行權(quán)限校驗(yàn),登錄狀態(tài)下登陸頁除外
// 因?yàn)榈顷懞螅瑹o法跳轉(zhuǎn)到登陸頁
// 這部分代碼,是為了在非登陸狀態(tài)下,訪問不需要權(quán)限校驗(yàn)的路由
const targetRouterConfig = routerConfig.find(
(item) => item.path === pathname
);
console.log(targetRouterConfig);
if (targetRouterConfig && !targetRouterConfig.auth && !isLogin) {
const {component} = targetRouterConfig;
return <Route exact path={pathname} component={component}/>;
}
if (isLogin) {
// 如果是登陸狀態(tài),想要跳轉(zhuǎn)到登陸,重定向到主頁
if (pathname === "/login") {
return <Redirect to="/"/>;
} else {
// 如果路由合法,就跳轉(zhuǎn)到相應(yīng)的路由
if (targetRouterConfig) {
return (
<Route path={pathname} component={targetRouterConfig.component}/>
);
} else {
// 如果路由不合法,重定向到 404 頁面
return <Redirect to="/error"/>;
}
}
} else {
// 非登陸狀態(tài)下,當(dāng)路由合法時(shí)且需要權(quán)限校驗(yàn)時(shí),跳轉(zhuǎn)到登陸頁面,要求登陸
if (targetRouterConfig && targetRouterConfig.auth) {
return <Redirect to="/login"/>;
} else {
// 非登陸狀態(tài)下,路由不合法時(shí),重定向至 404
return <Redirect to="/error"/>;
}
}
}
}
export default FrontendAuth;
然后,定義 Router 組件,在App.js中,該組件是經(jīng)過高階組件包裝后的結(jié)果:
import './App.less';
import React, {Fragment} from "react";
import {Switch} from 'react-router-dom'
import FrontendAuth from "./FrontendAuth";
import {routerMap} from "./routerMap";
function App() {
return (
<Fragment>
{/*只匹配一個(gè),匹配成功就不往下匹配,效率高*/}
<Switch>
<FrontendAuth routerConfig={routerMap}/>
</Switch>
</Fragment>
);
}
export default App;
測(cè)試

到此這篇關(guān)于react路由守衛(wèi)的實(shí)現(xiàn)(路由攔截)的文章就介紹到這了,更多相關(guān)react路由守衛(wèi)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
從零搭建Webpack5-react腳手架的實(shí)現(xiàn)步驟(附源碼)
本文主要介紹了從零搭建Webpack5-react腳手架的實(shí)現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08
React+CSS 實(shí)現(xiàn)繪制橫向柱狀圖
這篇文章主要介紹了React+CSS 實(shí)現(xiàn)繪制橫向柱狀圖,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09
react實(shí)現(xiàn)導(dǎo)航欄二級(jí)聯(lián)動(dòng)
這篇文章主要為大家詳細(xì)介紹了react實(shí)現(xiàn)導(dǎo)航欄二級(jí)聯(lián)動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
關(guān)于hooks中useEffect()的使用總結(jié)
這篇文章主要介紹了關(guān)于hooks中useEffect()的使用總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01
React Hooks常用場(chǎng)景的使用(小結(jié))
這篇文章主要介紹了React Hooks常用場(chǎng)景的使用,根據(jù)使用場(chǎng)景分別進(jìn)行舉例說明,幫助你認(rèn)識(shí)理解并可以熟練運(yùn)用 React Hooks 大部分特性,感興趣的可以了解一下2021-04-04

