vue組件級路由鉤子函數(beforeRouteEnter/beforeRouteUpdate/beforeRouteLeave)

1.vue組件級路由鉤子函數(beforeRouteEnter/beforeRouteUpdate/beforeRouteLeave):http://www.menvscode.com/detail/5a28b74c10c98d0e654c1bcehtml

2.vue使用vue-router beforEach實現判斷用戶登陸跳轉路由篩選:https://www.colabug.com/3306814.htmlvue

 

 

在開發webApp的時候,考慮到用戶體驗,常常會把不須要調用我的數據的頁面設置成遊客能夠訪問,而當用戶進入到一些須要我的數據的,例如購物車,我的中心,個人錢包等等,在進行登陸的驗證判斷,若是判斷已經登陸,則顯示頁面,若是判斷未登陸,則直接跳轉到登陸頁面提示用戶登陸,今天就來分享下如何使用vue-router的beforEach方法來實現這個需求。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的三個參數:數組

  1. to:router即將進入的路由對象。
  2. from:當前導航正要離開的路由。
  3. 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函數

在以上這種狀況下,spa

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方法進行路由攔截了,咱們不只僅能夠只作登陸判斷,經過這個方法能夠實現不少需求,只要是有關路由跳轉的均可以,在下只是拋磚引玉,若是有哪裏不對的地方或者有更好的方法能夠直接在評論告訴我,很是感謝。

相關文章
相關標籤/搜索