1. 程式人生 > 其它 >vue路由——進階篇(一)

vue路由——進階篇(一)

技術標籤:vuevue.js

在vue路由的基礎篇中,我們主要講解了如何使用路由。那麼進階篇我們主要去了解一下路由守衛等知識。

路由守衛

vue-router 提供的路由守衛主要用於**通過跳轉或取消的方式守衛導航,或者新增許可權驗證、資料獲取等業務邏輯。**路由守衛主要分為:全域性守衛、路由獨享的守衛和元件內守衛

每一個導航守衛都有三個引數:tofromnext,除了router.afterEach()方法之外。解析三個引數:

  1. to: Route: 即將要進入的目標路由物件
  2. from: Route: 當前導航正要離開的路由
  3. next: Function:一定要呼叫該方法來 resolve 這個鉤子。
    • next():進行管道中的下一個鉤子。如果全部鉤子執行完了,則導航的狀態就是 confirmed (確認的)。
    • next(false):中斷當前的導航。如果瀏覽器的 URL 改變了 (可能是使用者手動或者瀏覽器後退按鈕),那麼 URL 地址會重置到 from 路由對應的地址。
    • next(’/’) 或者 next({ path: ‘/’ }): 跳轉到一個不同的地址。當前的導航被中斷,然後進行一個新的導航。你可以向 next 傳遞任意位置物件,且允許設定諸如 replace: truename: 'home' 之類的選項以及任何用在 router-linkto prop 或router.push 中的選項。當使用這種方式的時候,會重新執行全域性前置守衛
    • next(error): (2.4.0+) 如果傳入 next 的引數是一個 Error 例項,則導航會被終止且該錯誤會被傳遞給 router.onError() 註冊過的回撥。

全域性守衛

這篇我們主要去了解一下全域性守衛。全域性守衛是用在全域性的,專案中的任何路由和元件都能經過去全域性守衛。全域性守衛分為:全域性前置守衛、全域性解析守衛和全域性後置鉤子。

全域性前置守衛,是用在導航觸發時,是全域性守衛中最先被觸發的守衛,是路由守衛中第二個被觸發的守衛,可以通過router.beforeEach()方法註冊前置守衛 。當存在多個前置守衛時,全域性前置守衛按照建立順序呼叫。

router.beforeEach((to, from, next) => {
    console.log("這個是我要進入的路由物件", to);
    console.
log("這個是我要離開的路由物件", from); if (to.path == '/books') { next(); } else { next('/books'); } })

在這裡插入圖片描述
全域性解析守衛,使用router.beforeResolve()註冊。和全域性前置守衛類似,在導航確認之前,在所有元件內守衛和非同步路由元件被解析之後,解析守衛被呼叫。簡單來說,**這個全域性守衛在元件內守衛和路由獨享守衛全部呼叫之後呼叫,但在全域性後置鉤子守衛之前呼叫。**它的使用方法和router.beforeEach()方法一樣。

全域性後置鉤子,使用router.afterEach()方法註冊。它與守衛不同,它沒有第三個引數,也不會改變導航。

路由獨享的守衛

路由獨享的守衛,是在 Router 構建選項routes選項中配置的,使用beforeEnter選項直接定義。它只在該定義它的元件上生效,在全域性前置守衛被呼叫之後,在進入路由元件之前呼叫。 毫無疑問它的使用方法和全域性前置守衛一樣。

{
  path: '/',
  component: Index,
  beforeEnter: (to, from, next) => {
    console.log("我進入了首頁的路由獨享的守衛");
     next();
  }
}

元件內守衛

元件內守衛有三個,分別是beforeRouteEnterbeforeRouteUpdatebeforeRouteLeave。它們的使用方法,和呼叫時機如下:

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

在元件內守衛中最特殊的是beforeRouteEnter守衛,這個守衛是所有守衛中唯一一個支援回撥函式的守衛。這個守衛在導航被確認的時候執行回撥,並且把元件例項作為回撥方法的引數。

beforeRouteEnter (to, from, next) {
  next(vm => {
    // 通過 `vm` 訪問元件例項
  })
}

在上面例項中,我們闡述了,元件內的三種守衛。beforeRouteEnter守衛當元件被渲染的時候被呼叫,beforeRouteLeave守衛當離開改元件(頁面上不顯示該元件)時呼叫,beforeRouteUpdate守衛當元件重新渲染時呼叫。

完整的導航解析流程

當從一個URL切換到另外一個URL時,所有守衛執行的流程。

  1. 第一步:觸發導航;
  2. 第二步:從原先的URL離開,表明改頁面的元件全部被銷燬,所以元件內守衛beforeRouteLeave被呼叫;
  3. 第三步:進入新的 URL 地址,則全域性前置守衛beforeEach被呼叫;
  4. 第四步:如果修改後的 URL 地址,也複用了原先 URL 地址的元件,則呼叫該元件的元件內守衛beforeRouteUpdate如果沒有複用則這步忽略
  5. 第五步:對路由進行匹配,在匹配到正確的路由之後,呼叫路由獨享的守衛beforeEnter
  6. 第六步:解析非同步路由元件;
  7. 第七步:呼叫元件內守衛beforeRouteEnter
  8. 第八步:呼叫全域性解析守衛beforeResolve
  9. 第九步:導航被確認。
  10. 第十步:呼叫全域性後置鉤子afterEach
  11. 第十一步:觸發 DOM 更新;
  12. 第十二步:在完成以上過程之後,呼叫 元件內守衛beforeRouteEnter中傳給 next 的回撥函式,建立好的元件例項會作為回撥函式的引數傳入。