距離上一篇文章,彷佛已通過去很久了。javascript
確實是最近相對忙了一點,自己是用vue重構以前一個傳統的項目,就本身一我的寫。並且,在稍微閒暇之餘,想着同時用react也重構一遍,也算是對react的學習吧!畢竟只有實際應用纔是最好的學習方法。vue
在vue應用中,咱們經常涉及到一個概念就是路由導航守衛。java
在作用戶登陸確認和身份標識時,經常須要進行路由的導航守衛。react
當前的項目需求:vue-router
用戶若是想要使用咱們的平臺,必須進行登陸,用戶登陸以後,依據用戶身份,確認其是車主,仍是貨主,分別展現不一樣的應用內容。api
因此路由導航守衛的大概是這樣的:react-router
在用戶輸入應用網址以後,先檢測是否登陸,若是未登陸,二次跳轉到登陸頁面,若是已經登陸,那麼判斷用戶身份,若是車主,跳轉到車主對應的頁面,若是是貨主,跳轉到貨主對應的頁面。ide
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()跳轉到用戶輸入的頁面。this
第二個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的導航守衛更簡單一點呢!