Vue - 路由守衛(路由的生命週期)

路由守衛是什麼?

官方解釋:javascript

「導航」表示路由正在發生改變。正如其名,vue-router提供的導航守衛主要用來經過跳轉或取消的方式守衛導航。有多種機會植入路由導航過程當中:全局的, 單個路由獨享的, 或者組件級的。

簡單的說,導航守衛就是路由跳轉過程當中的一些鉤子函數。路由跳轉是一個大的過程,這個大的過程分爲跳轉前中後等等細小的過程,在每個過程當中都有一函數,這個函數能讓你操做一些其餘的事兒,這就是導航守衛。相似於組件生命週期鉤子函數html

路由守衛分類

【1】全局守衛:是指路由實例上直接操做的鉤子函數,特色是全部路由配置的組件都會觸發,直白點就是觸發路由就會觸發這些鉤子函數vue

  • beforeEach(to,from, next)
  • beforeResolve(to,from, next)
  • afterEach(to,from)

【2】路由守衛: 是指在單個路由配置的時候也能夠設置的鉤子函數java

  • beforeEnter(to,from, next)

【3】組件守衛:是指在組件內執行的鉤子函數,相似於組件內的生命週期,至關於爲配置路由的組件添加的生命週期鉤子函數。vue-router

  • beforeRouteEnter(to,from, next)
  • beforeRouteUpdate(to,from, next)
  • beforeRouteLeave(to,from, next)

路由守衛回調參數介紹

to:即將要進入的目標路由對象;瀏覽器

from:即將要離開的路由對象;異步

next:涉及到next參數的鉤子函數,必須調用next()方法來resolve這個鉤子,不然路由會中斷在這,不會繼續往下執行函數

  • next():進行管道中的下一個鉤子。若是所有鉤子執行完了,則導航的狀態就是confirmed(確認的)。
  • next( false )中斷當前的導航。若是瀏覽器的 URL 改變了 (多是用戶手動或者瀏覽器後退按鈕),那麼 URL 地址會重置到from路由對應的地址。
  • next( ' / ')或者next({ paht:' / ' }):跳轉到一個不一樣的地址。當前的導航被中斷,而後進行一個新的導航。可傳遞的參數能夠是router-link標籤中的to屬性參數或router.push中的選項
  • next( error ):若是傳入next的參數是一個Error實例,則導航會被終止且該錯誤會被傳遞給router.onError()註冊過的回調。

路由守衛詳解

【1】全局解析守衛(beforeEach): 在路由跳轉前觸發,這個鉤子做用主要是用於登陸驗證,也就是路由還沒跳轉提早告知,以避免跳轉了再通知就爲時已晚。ui

const router = new VueRouter({ ... })

router.beforeEach((to, from, next) => {
  // ...
})複製代碼

【2】全局解析守衛(beforeResolve): 這個鉤子和beforeEach相似,也是路由跳轉前觸發,區別是在導航被確認以前,同時在全部組件內守衛和異步路由組件被解析以後,即在 beforeEach 和 組件內beforeRouteEnter 以後,afterEach以前調用。this

【3】全局後置鉤子(afterEach): 和beforeEach相反,它是在路由跳轉完成後觸發,它發生在beforeEach和beforeResolve以後,beforeRouteEnter(組件內守衛)以前。這些鉤子不會接受next函數也不會改變導航自己

router.afterEach((to, from) => {
  // ...
})複製代碼

【4】路由獨享守衛(beforeEnter): 和beforeEach徹底相同,若是兩個都設置了,beforeEnter則在beforeEach以後緊隨執行。在路由配置上直接定義beforeEnter守衛

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // ...
      }
    }
  ]
})複製代碼

【5】組件內的守衛:

<template> ... </template> <script> export default{ data(){ //... }, beforeRouteEnter (to, from, next) { // 在渲染該組件的對應路由被 confirm 前調用 // 不!能!獲取組件實例 `this` // 由於當守衛執行前,組件實例還沒被建立 }, beforeRouteUpdate (to, from, next) { // 在當前路由改變,可是該組件被複用時調用 // 舉例來講,對於一個帶有動態參數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候, // 因爲會渲染一樣的 Foo 組件,所以組件實例會被複用。而這個鉤子就會在這個狀況下被調用。 // 能夠訪問組件實例 `this` }, beforeRouteLeave (to, from, next) { // 導航離開該組件的對應路由時調用 // 能夠訪問組件實例 `this` } } </script> <style> ... </style>複製代碼

1. beforeRouteEnter:該鉤子在全局守衛beforeEach和獨享守衛beforeEnter以後,全局beforeResolve和全局afterEach以前調用,要注意的是該守衛內訪問不到組件的實例,也就是this爲undefined。由於它在組件生命週期beforeCreate階段觸發,此時的新組件尚未被建立。在這個鉤子函數中,能夠經過傳一個回調給 next來訪問組件實例。在導航被確認的時候執行回調,而且把組件實例做爲回調方法的參數。

beforeRouteEnter (to, from, next) {
  next(vm => {
    // 經過 `vm` 訪問組件實例
  })
}複製代碼

2. beforeRouteUpdate:在當前路由改變時,而且該組件被複用時調用,能夠經過this訪問實例。

3. beforeRouteLeave:導航離開該組件的對應路由時調用,能夠訪問組件實例this。這個離開守衛一般用來禁止用戶在還未保存修改前忽然離開。該導航能夠經過next( false )來取消。

beforeRouteLeave (to, from , next) {
  const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
  if (answer) {
    next()
  } else {
    next(false)
  }
}複製代碼

完整的導航解析流程

  1. 觸發進入其它路由
  2. 調用要離開路由的組件守衛beforeRouteLeave
  3. 調用全局的前置守衛beforeEach
  4. 在重用的組件裏調用 beforeRouteUpdate
  5. 在路由配置裏調用 beforeEnter
  6. 解析異步路由組件
  7. 在將要進入的路由組件中調用beforeRouteEnter
  8. 調用全局的解析守衛beforeResolve
  9. 導航被確認
  10. 調用全局的後置鉤子afterEach
  11. 觸發 DOM 更新mounted
  12. 執行beforeRouteEnter守衛中傳給 next的回調函數。

相關文章
相關標籤/搜索