1. 程式人生 > >react-router-dom實現全局路由登陸攔截

react-router-dom實現全局路由登陸攔截

狀態 統一管理 hist pan erro extend urn app.js cati

  相比與vue的路由集中式管理,能夠很好的進行統一的路由操作,react的路由看起來更亂,想要進行像vue的全局路由管理不是那麽得心應手。在我們的項目中,有很多頁面是需要登陸權限驗證的,最好的方式就是能夠統一管理,而不是每個頁面都要單獨處理,下面是我的實現方法:

  首先我們建一個文件routerMap.js用來存儲所有的路由信息,定義需要登陸攔截的頁面(auth):

技術分享圖片
//routerMap.js

import Index from ‘../containers‘;
import Detail from ‘../containers/detail‘;
import Home from 
‘../containers/home‘; import List from ‘../containers/list‘; import Topics from ‘../containers/topics‘; import Parents from ‘../containers/passValue/parents‘; import Children from ‘../containers/passValue/children‘; import Request from ‘../containers/ajax‘; import Like from ‘../containers/like‘; import PopModule from
‘../containers/popModule/popModule‘; import Reduxs from ‘../containers/redux/redux‘; import Login from ‘../containers/login/login‘; import Workers from ‘../containers/worker/worker‘; import IndexedDB from ‘../containers/indexedDB/indexedDB‘; export default [ { path: "/", name: "App", component: Index }, { path:
"/home", name: "Home", component: Home }, { path: "/topics", name: "Topics", component: Topics }, { path: "/detail/:id", name: "Detail", component: Detail }, { path: "/list", name: "List", component: List }, { path: "/parents", name: "Parents", component: Parents }, { path: "/children", name: "Children", component: Children }, { path: "/ajax", name: "Request", component: Request, auth: true }, { path: "/like", name: "Like", component: Like, auth: true }, { path: "/popModule", name: "PopModule", component: PopModule, auth: true }, { path: "/redux", name: "Reduxs", component: Reduxs, auth: true }, { path: "/login", name: "Login", component: Login }, { path: "/worker", name: "Worker", component: Workers }, { path: "/indexedDB", name: "indexedDB", component: IndexedDB } ]
View Code

  然後在App.js裏面引入:

 1 //App.js
 2 import React from ‘react‘;
 3 import {
 4   BrowserRouter as Router,
 5   Route,
 6   Switch,
 7   Redirect
 8 } from ‘react-router-dom‘;
 9 import { connect } from ‘react-redux‘
10 import Routers from ‘./router/routerMap‘
11 
12 // 公共頭部組件
13 import Header from ‘./common/header‘
14 // 404頁面
15 import NotFound from ‘./containers/notFound‘
16 
17 
18 class App extends React.Component {
19   constructor(props) {
20     super(props)
21   }
22   render() {
23     let token = this.props.token
24     return (
25       <Router>
26         <div>
27           <Header />
28           <Switch>
29             {Routers.map((item, index) => {
30               return <Route key={index} path={item.path} exact render={props =>
31                 (!item.auth ? (<item.component {...props} />) : (token ? <item.component {...props} /> : <Redirect to={{
32                   pathname: ‘/login‘,
33                   state: { from: props.location }
34                 }} />)
35                 )} />
36             })}
37             // 所有錯誤路由跳轉頁面
38             <Route component={NotFound} />
39           </Switch>
40         </div>
41       </Router>
42     )
43   }
44 }
45 
46 // redux拿到token並掛載到App的props上面
47 const mapStateToProps = (state, ownProps) => {
48   return { token: state.token }
49 }
50 
51 export default connect(mapStateToProps)(App)

  以上代碼最重要的點是Route組建裏面用render屬性替換component來渲染頁面,根據routerMap.js中的每一條路由信息中的auth(自定義)字段來區分是否需要進行登陸攔截,再根據redux裏面的token字段來判斷是不是登陸狀態,然後進行相關的操作。如果已經攔截了就把當前的路由通過Redirectstate來傳遞到登陸頁面,在登陸頁面打印this.props來看控制臺的輸出:

技術分享圖片

  以上紅框內的信息即為重定向之前的頁面信息,如果登陸成功之後回跳from.pathname即可:

// 登陸成功方法 login.jsx
setToken() {
  let token = this.state.user + this.state.pwd
  if (!token) return
  let RedirectUrl = this.props.location.state ? this.props.location.state.from.pathname : ‘/‘
  // 修改redux中的token值
  this.props.changeActive(token)
  // 登陸成功之後的跳轉
  this.props.history.push(RedirectUrl)
}

  react全局的登陸攔截方法到此就完成了

react-router-dom實現全局路由登陸攔截