天天看點

React-router 5.2.0 + React 16.13.1 路由守衛的簡單實作

這幾天從Vue轉react,學習一下全家桶。

React-router很強大, 但是文檔是純英文而且不直接提供類似Vue的路由守衛,是以需要手寫路由守衛,下面是一個寫法,可參考,路由守衛的作用都知道,就不再贅述,最基礎的功能就是對登入狀态進行一個簡單的驗證。

首先建立幾個頁面:

  1. Home:首頁
  2. Login:登入
  3. Error:路由出錯的展示頁面(404)

然後建立router.js用來編寫路由配置

步驟:

1.import必要的元件:

import React from 'react';
import Login from './Login/index.js';
import Home from './Home/index.js';
import ErrorPage from './Error/index.js';
import {
  BrowserRouter as Router ,
  Switch ,
  Route ,
  useHistory ,
  useLocation,
  Redirect
} from 'react-router-dom';
           

2.配置路由數組:

const routerArr = [
  {
      path:"/login",
      component:Login,
  },
  {
      path:"/error",
      component:ErrorPage
  },
  {
      path:"/",
      component:Home
  }
]
           

3.編寫路由守衛:

function RouterGuard(){
  let history = useHistory();
  let location = useLocation();
  // 拿到路徑
  let { pathname } = location;
  // 拿到目前路由
  let thisRoute = routerArr.find((el)=>el['path'] == pathname);
  let isLogin = sessionStorage.getItem('isLogin');
  //如果沒登入且頁面為登入頁的話渲染登入頁
  if(pathname == '/login' && !isLogin){
    return <Route path={pathname} component={thisRoute['component']} exact/>
  }
  //如果已經登入渲染頁面
  if(isLogin){
    //如果登陸了跳轉login頁,則重定向
    if(pathname == '/login'){
      return <Redirect to="/" />
    }
    // 判定路由是否存在,如果存在正常渲染
    if(thisRoute){
      return <Route path={pathname} component={thisRoute['component']} exact/>
    }else{
      //否則進入404頁面
      return <Redirect to="/error" />;
    }
  }else{
    // 否則跳轉到登入頁
    return <Redirect to="/login" />
  }
}
           

可以做更多的拓展,比如通過在路由配置中添加字段實作傳值/條件跳轉等功能

4.渲染Router并抛出元件:

function Routes(){
  return (
    <Router>
      <Switch>
        <RouterGuard />
      </Switch>
    </Router>
  )
}
export default Routes
           

然後渲染即可,子元件均可通過:

this.props.history 
this.props.location
           

等方式的到父元件的方法,友善進行跳轉等調用。

完整的Router.js:

import React from 'react';
import Login from './Login/index.js';
import Home from './Home/index.js';
import ErrorPage from './Error/index.js';
import {
  BrowserRouter as Router ,
  Switch ,
  Route , 
  useHistory ,
  useLocation,
  Redirect
} from 'react-router-dom';
const routerArr = [
  {
      path:"/login",
      component:Login,
  },
  {
      path:"/error",
      component:ErrorPage
  },
  {
      path:"/",
      component:Home
  }
]
​
function RouterGuard(){
  let history = useHistory();
  let location = useLocation();
  let { pathname } = location;
  // 拿到目前路由
  let thisRoute = routerArr.find((el)=>el['path'] == pathname);
  let isLogin = sessionStorage.getItem('isLogin');
  //如果沒登入且頁面為登入頁的話渲染登入頁
  if(pathname == '/login' && !isLogin){
    return <Route path={pathname} component={thisRoute['component']} exact/>
  }
  //如果已經登入渲染頁面
  if(isLogin){
    //如果登陸了跳轉login頁,則重定向
    if(pathname == '/login'){
      return <Redirect to="/" />
    }
    if(thisRoute){
      return <Route path={pathname} component={thisRoute['component']} exact/>
    }else{
      return <Redirect to="/error" />;
    }
  }else{
    // 否則跳轉到登入頁
    return <Redirect to="/login" />
  }
}
function Routes(){
  return (
    <Router>
      <Switch>
        <RouterGuard />
      </Switch>
    </Router>
  )
}
export default Routes
           

繼續閱讀