1. 程式人生 > 其它 >Vue的鉤子函式[路由導航守衛、keep-alive、生命週期鉤子]

Vue的鉤子函式[路由導航守衛、keep-alive、生命週期鉤子]

說到Vue的鉤子函式,可能很多人只停留在一些很簡單常用的鉤子(created,mounted),而且對於裡面的區別,什麼時候該用什麼鉤子,並沒有仔細的去研究過,且Vue的生命週期在面試中也算是比較高頻的考點,那麼該如何回答這類問題,讓人有眼前一亮的感覺呢...

Vue-Router導航守衛:

有的時候,我們需要通過路由來進行一些操作,比如最常見的登入許可權驗證,當用戶滿足條件時,才讓其進入導航,否則就取消跳轉,並跳到登入頁面讓其登入。

為此我們有很多種方法可以植入路由的導航過程:全域性的, 單個路由獨享的, 或者元件級的,推薦優先閱讀路由文件

全域性守衛

vue-router全域性有三個守衛:

  1. router.beforeEach 全域性前置守衛 進入路由之前
  2. router.beforeResolve 全域性解析守衛(2.5.0+) 在beforeRouteEnter呼叫之後呼叫
  3. router.afterEach 全域性後置鉤子 進入路由之後

使用方法

    // main.js 入口檔案
    import router from './router'; // 引入路由
    router.beforeEach((to, from, next) => { 
      next();
    });
    router.beforeResolve((to, from, next) => {
      next();
    });
    router.afterEach((to, from) => {
      console.log('afterEach 全域性後置鉤子');
    });

to,from,next 這三個引數:

to和from是將要進入和將要離開的路由物件,路由物件指的是平時通過this.$route獲取到的路由物件。

next:Function 這個引數是個函式,且必須呼叫,否則不能進入路由(頁面空白)。

  • next() 進入該路由。

  • next(false): 取消進入路由,url地址重置為from路由地址(也就是將要離開的路由地址)。

  • next 跳轉新路由,當前的導航被中斷,重新開始一個新的導航。

  我們可以這樣跳轉:next('path地址')或者next({path:''})或者next({name:''})
  且允許設定諸如 replace: true、name: 'home' 之類的選項
  以及你用在router-link或router.push的物件選項。

路由獨享守衛

如果你不想全域性配置守衛的話,你可以為某些路由單獨配置守衛:

    const router = new VueRouter({
      routes: [
        {
          path: '/foo',
          component: Foo,
          beforeEnter: (to, from, next) => { 
            // 引數用法什麼的都一樣,呼叫順序在全域性前置守衛後面,所以不會被全域性守衛覆蓋
            // ...
          }
        }
      ]
    })

路由元件內的守衛:

  1. beforeRouteEnter 進入路由前
  2. beforeRouteUpdate (2.2) 路由複用同一個元件時
  3. beforeRouteLeave 離開當前路由時

文件中的介紹:

  beforeRouteEnter (to, from, next) {
    // 在路由獨享守衛後呼叫 不!能!獲取元件例項 `this`,元件例項還沒被建立
  },
  beforeRouteUpdate (to, from, next) {
    // 在當前路由改變,但是該元件被複用時呼叫 可以訪問元件例項 `this`
    // 舉例來說,對於一個帶有動態引數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候,
    // 由於會渲染同樣的 Foo 元件,因此元件例項會被複用。而這個鉤子就會在這個情況下被呼叫。
  },
  beforeRouteLeave (to, from, next) {
    // 導航離開該元件的對應路由時呼叫,可以訪問元件例項 `this`
  }

beforeRouteEnter訪問this

因為鉤子在元件例項還沒被建立的時候呼叫,所以不能獲取元件例項 this,可以通過傳一個回撥給next來訪問元件例項 。

但是回撥的執行時機在mounted後面,所以在我看來這裡對this的訪問意義不太大,可以放在created或者mounted裡面。

    beforeRouteEnter (to, from, next) {
    console.log('在路由獨享守衛後呼叫');
      next(vm => {
        // 通過 `vm` 訪問元件例項`this` 執行回撥的時機在mounted後面,
      })
    }

beforeRouteLeave:

導航離開該元件的對應路由時呼叫,我們用它來禁止使用者離開,比如還未儲存草稿,或者在使用者離開前,將setInterval銷燬,防止離開之後,定時器還在呼叫。

    beforeRouteLeave (to, from , next) {
      if (文章儲存) {
        next(); // 允許離開或者可以跳到別的路由 上面講過了
      } else {
        next(false); // 取消離開
      }
    }