全局前置守衛beforeEach
beforeEach 守衛是異步解析執行,此時導航在所有守衛 resolve 完之前一直處於 等待中。
每個守衛方法接收三個參數:
-
from: Route
: 當前導航正要離開的路由 -
next: Function
: 一定要調用該方法來 resolve 這個鈎子。執行效果依賴next
方法的調用參數。確保要調用next
方法,否則鈎子就不會被 resolved -
router.beforeEach(async (to, from, next) => { const localId = localStorage.getItem('userId'); if (to.name === 'login') { // 訪問login,緩存判斷 if (localId) { //有緩存,訪問主頁 next({ name: 'main' }); } else {// 無緩存,跳轉登錄頁 next(); } } else if (to.name !== 'login' && localId) { // 訪問非登錄頁,有緩存,繼續跳轉該頁面 next(); } else if (to.name !== 'login' && !localId) { next({ name: 'login' }); // 訪問非登錄頁,無緩存,跳轉login } });
在這里需要注意的是,通過next({name:'xxx'}),就要通過to.name ==='login'去判斷;如果是通過next({path:'xxx'})跳轉,就要通過to.path==='/login'去判斷,他們必須一一對應。這兩種方式是改變路由的跳轉路徑,但是不管怎么樣,最后一定要執行next()才可以被resolved。如果next()沒有被執行,就會出現無限循環,最后瀏覽器就崩了!網上有很多文章寫了關於beforeEach無限循環的問題,終其原因就是沒有執行到next()。如果你的beforeEach出現了無限循環,耐心地在beforeEach函數中打上斷點,檢查自己的邏輯是不是沒對。
另外需要說的一點是,在beforeEach里可能會有異步請求,如后台請求菜單,獲取用戶信息等等,需要在調用store的方法,調用時,beforeEach使用async修飾(如上文代碼所示),函數調用時加上await關鍵字使得同步執行,如 await store.dispatch('getMenus', localId);這里也算是一個坑,需要格外注意。
總結一下
- beforeEach收尾中必須要執行next()才不會出現無限循環
- 路由跳轉時,屬性需要一致,to.name/to.path等
- 在beforeEach中共調用store的異步函數,beforeEach加上async修飾,函數調用使用await store.dispatch, await store.dispatch('getMenus', localId);
如果文章對你有幫助,麻煩幫忙點個贊哦!嘿嘿!做一個靠譜的技術博主!