1.vue組件級路由鈎子函數(beforeRouteEnter/beforeRouteUpdate/beforeRouteLeave):http://www.menvscode.com/detail/5a28b74c10c98d0e654c1bce
2.vue使用vue-router beforEach實現判斷用戶登錄跳轉路由篩選:https://www.colabug.com/3306814.html
在開發webApp的時候,考慮到用戶體驗,經常會把不需要調用個人數據的頁面設置成游客可以訪問,而當用戶進入到一些需要個人數據的,例如購物車,個人中心,我的錢包等等,在進行登錄的驗證判斷,如果判斷已經登錄,則顯示頁面,如果判斷未登錄,則直接跳轉到登錄頁面提示用戶登錄,今天就來分享下如何使用vue-router的beforEach方法來實現這個需求。
實現
本篇文章默認您已經會使用 webpack
或者 vue-cli
來進行環境的搭建,並且具有一定的vue基礎,如果您目前是一個新手,那么網上搜索一下就好,相關文章非常多,這里就不再贅述了。 話不多說,直接上代碼。 為了方便日后代碼的可維護性,我把相關方法寫在了一個新建的filter.js文件里

接下來進入filter.js文件中,首先引入vue-router: import router from "./router";
然后我們使用 router.beforEach
方法:
router.beforeEach((to, from, next) => { //根據字段判斷是否路由過濾 if (to.matched.some(record => record.meta.auth)) { if (getToken() !== null) { next() } else { //防止無限循環 if (to.name === 'login') { next(); return } next({ path: '/login', }); } } else { next()//若點擊的是不需要驗證的頁面,則進行正常的路由跳轉 } });
beforEach其實是vur-router的鈎子函數,可以理解為每個router跳轉之前都會調用的一個方法,既然有before同理當然也有afterEach,這個我們以后再講。
首先來解釋下beforEach的三個參數:
- to:router即將進入的路由對象。
- from:當前導航正要離開的路由。
- next:一個function,一定要調用該方法來 resolve 這個鈎子。執行效果依賴 next 方法的調用參數。
next()
: 進行管道中的下一個鈎子。如果全部鈎子執行完了,則導航的狀態就是 confirmed (確認的)。next(false)
: 中斷當前的導航。如果瀏覽器的 URL 改變了(可能是用戶手動或者瀏覽器后退按鈕),那么 URL 地址會重置到 from 路由對應的地址。- next('/') 或者 next({ path: '/' }): 跳轉到一個不同的地址。當前的導航被中斷,然后進行一個新的導航。 你可以向 next 傳遞任意位置對象,且允許設置諸如 replace: true、name: ‘home’ 之類的選項以及任何用在 router-link 的 to prop 或 router.push 中的選項,注意,next可以通過query傳遞參數。
next(error)
: (2.4.0+) 如果傳入 next 的參數是一個 Error 實例,則導航會被終止且該錯誤會被傳遞給 router.onError() 注冊過的回調。
說明
好了,看到這里可能有些人還是沒有理解,沒關系,接下來我舉個例子就可以明白了。
假設我們目前有三個路由:/home,/mine,/login
我們初始進入為/home
,這時候點擊跳轉/mine
,但是由於我們沒有登錄,所以會自動跳轉到/login
在以上這種情況下,
to:代表着路由 /mine
,我們要進入的路由。
from:代表着路由 /home
,我們將要離開的路由。
注意,使用beforEach最后必須要調用 next()
,否則會報錯,如果不傳參數,我們就會成功進入到 /mine
,如果我們傳遞參數,例如 next('/login')
,那么我們在點擊任何路由都會跳轉到 /login
界面。
但是我們的需求是只有點擊需要進行登錄驗證的頁面才進行攔截跳轉,因此,我們需要加一些判斷條件來進行路由的篩選。
if (to.matched.some(record => record.meta.auth)) { if (getToken() !== null) { next() } }
這里的to就是上面講的參數to, to.matched
是一個對象數組,里面有to指向路由的相關信息,例如:path,name,meta等等。
我們用該數組調用some()方法根據返回值 true
或者 false
來進行判斷,所以我們要在router.js路由配置文件中為我們需要驗證登錄判斷跳轉的路由添加一個字段來作為判斷條件
{ path: '/mine', name: 'mine', component: mine, meta:{auth:true} //我們自己添加的字段 }
由於給路由添加了 meta:{auth:true}
,所以我們的 to.matched.some(record => record.meta.auth)
會返回 true
,這時我們就可以做登錄判斷了,我的項目是通過把token存入到 localstorage
來進行判斷的, getToken()是我封裝的一個獲取 localstorage
方法。
if (getToken() !== null) { next()//若token不為null,則進行路由跳轉 }
如果沒有token,我們下一步繼續進行判斷,也就是最終目的,進行路由攔截,跳轉到登錄頁
else { next({ path: '/login', }); }
但是這時候我們會遇到新的問題,打開控制台會發現路由會無限的循環並最終崩潰,這是什么原因呢?仔細閱讀上文紅色加粗,我們可以理解為
next() next({ path: '/login', });
也就是說beforeEach()必須調用next(),否則就會出現無限循環
next() 和 next('xxx') 是不一樣的,區別就是前者不會再次調用router.beforeEach(),后者會。而由於我們沒有token,所以在重新調用router.beforeEach()后,會再次進入到
else { next({ path: '/login', }); }
所以造成了無限循環,解決這個問題的方法也很簡單,我們在 next({ path: '/login', });
之前增加一個判斷條件
if (to.name === 'login') { next(); return }
如果我們to的定向路由 name == 'login'
,則執行 next();
並return終止代碼運行。
以上就是通過router.beforEach方法進行路由攔截了,我們不僅僅可以只做登錄判斷,通過這個方法可以實現很多需求,只要是有關路由跳轉的都可以,在下只是拋磚引玉,如果有哪里不對的地方或者有更好的方法可以直接在評論告訴我,非常感謝。