在開發webApp的時候,考慮到用戶體驗,常常會把不須要調用我的數據的頁面設置成遊客能夠訪問,而當用戶進入到一些須要我的數據的,例如購物車,我的中心,個人錢包等等,在進行登陸的驗證判斷,若是判斷已經登陸,則顯示頁面,若是判斷未登陸,則直接跳轉到登陸頁面提示用戶登陸,今天就來分享下如何使用vue-router的beforEach方法來實現這個需求。vue
實現webpack
本篇文章默認您已經會使用 webpack 或者 vue-cli 來進行環境的搭建,而且具備必定的vue基礎,若是您目前是一個新手,那麼網上搜索一下就好,相關文章很是多,這裏就再也不贅述了。 話很少說,直接上代碼。 爲了方便往後代碼的可維護性,我把相關方法寫在了一個新建的filter.js文件裏web
接下來進入filter.js文件中,首先引入vue-router: import router from "./router";而後咱們使用 router.beforEach 方法:vue-router
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,這個咱們之後再講。vue-cli
首先來解釋下beforEach的三個參數:數組
說明瀏覽器
好了,看到這裏可能有些人仍是沒有理解,不要緊,接下來我舉個例子就能夠明白了。函數
假設咱們目前有三個路由: /home,/mine,/loginlocalstorage
咱們初始進入爲 /home ,這時候點擊跳轉 /mine ,可是因爲咱們沒有登陸,因此會自動跳轉到 /login
在以上這種狀況下,code
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方法進行路由攔截了,咱們不只僅能夠只作登陸判斷,經過這個方法能夠實現不少需求,只要是有關路由跳轉的均可以,在下只是拋磚引玉,若是有哪裏不對的地方或者有更好的方法能夠直接在評論告訴我,很是感謝。