在react項目當中做導航守衛


  距離上一篇文章,似乎已經過去好久了。

  確實是最近相對忙了一點,本身是用vue重構之前一個傳統的項目,就自己一個人寫。而且,在稍微閑暇之余,想着同時用react也重構一遍,也算是對react的學習吧!畢竟只有實際應用才是最好的學習方法。

  在vue應用中,我們常常涉及到一個概念就是路由導航守衛。

  在做用戶登錄確認和身份標識時,常常需要進行路由的導航守衛。

  當前的項目需求:

    用戶如果想要使用我們的平台,必須進行登錄,用戶登錄之后,依據用戶身份,確認其是車主,還是貨主,分別展示不同的應用內容。

    所以路由導航守衛的大概是這樣的:

      在用戶輸入應用網址之后,先檢測是否登錄,如果未登錄,二次跳轉到登錄頁面,如果已經登錄,那么判斷用戶身份,如果車主,跳轉到車主對應的頁面,如果是貨主,跳轉到貨主對應的頁面。

  vue應用中,我們配置完路由之后,統一對路由進行守衛,直接上代碼吧!

router.beforeEach((to, from, next) => {
  NProgress.start()
  let identity = parseInt(localStorage.getItem('identity'), 10)
  if (whiteList.indexOf(to.path) !== -1) {
    next()
  } else {
    if (identity) {
      identity = identity === 2 ? 'shipper' : identity === 1 ? 'carrier' : ''
      // console.log('permission:', to.path, to.path.includes(identity))
      if (to.path.includes(identity)) {
        next()
      } else {
        next({
          name: identity,
          replace: true
        })
      }
    } else {
      next(`/login?redirect=${ to.path }`)
      NProgress.done()
    }
  }
})

router.afterEach((to, from) => {
  if (whiteList.indexOf(to.path) !== -1) {
    store.dispatch('fedLogOut')
    let identity = localStorage.getItem('identity')
    if (identity) localStorage.setItem('identity', null)
  }
  // finish progress bar
  NProgress.done()
})

  在router.beforeEach中,第一個if判斷的是,如果當前用戶直接輸入的是類似於login、registe這些頁面,在直接利用next()跳轉到用戶輸入的頁面。

  第二個if (identity)判斷的是用戶是否已經登錄了,如果不存在identity,也就是用戶未登錄,利用next(`/login?redirect=${ to.path }`)跳轉到login頁面。

  第三個if (to.path.includes(identity))判斷的是用戶輸入的網址和其身份標識是否匹配,如果是車主,輸入的網址是屬於貨主的,就重定向到車主所屬頁面。

  這一整個流程下來,就完成了路由的導航守衛。

  然而,當使用react進行重構的時候,發現一個尷尬的事情,react應用中,react-router4似乎並沒有提供上述類似的api供我們進行路由守衛,然而路由的導航守衛又必須要做,總不至於剛剛開始項目就這么夭折吧!這其中尋找react-router4的導航守衛過程,就不細說了,說多了都是淚啊。只說結果:react-router4就是以組件的方式提供的導航,他所有的類似於<Route/> <Link/>等等,都是組件。然后,想到什么了?

  來吧!

  當然:(路由怎么配置就不說了)與之前一樣,類似於login、register的頁面不需要任何守衛,直接進入就好了。需要守衛的是當用戶進入車主和貨主的頁面時。

  上代碼吧!

const { isLogined, identity } = this.state
    return isLogined ?
      (identity === 2 ?
        (<Spin spinning={this.props.loading}><Layout>
          <Header className="header">
            <div className="enterprise">南京星通北斗哦</div>
            <Navbar />
            <UserInfo className="userinfo" />
          </Header>
          <Content className="container">
            <Switch>
              {
                Shippers.map(route => {
                  return <Route path={"/shipper/" + route.path} component={route.component} key={route.path} />
                })
              }
              <Route path={"/" || "/shipper/*"} render={() => (
                <Redirect to="/shipper/home" />
              )} />
            </Switch>
          </Content>
        </Layout></Spin>) :
        <Redirect to="/carrier" />) :
      <Redirect to="/login" />

  看出什么了?兩個關鍵詞:isLogined、identity(代碼並不全,主要說的是思路,請勿直接使用)。

  isLogined判斷的是是否登錄,如果未登陸,<Redirect to="/login" />

  identity === 2判斷的是當前是否為貨主,如果不是,<Redirect to="/carrier" />

  只有這兩個判斷都滿足了,才能展示當前貨主所屬的組件,是不是完成了所謂的路由導航守衛?

  需要改變的是一個思想:react-router4當中,他就是組件,不滿足條件的話,直接Redirect,這就是所謂的導航守衛。思想轉變過來了,其實要做react-router4似乎比vue-router的導航守衛更簡單一點呢!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM