距離上一篇文章,似乎已經過去好久了。
確實是最近相對忙了一點,本身是用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的導航守衛更簡單一點呢!