1. 程式人生 > >詳解vue-router 中的導航鉤子

詳解vue-router 中的導航鉤子

vue-router 的導航鉤子,主要用來作用是攔截導航,讓他完成跳轉或取消。

有三種方式可以植入路由導航過程中:

  1. 全域性的

  2. 單個路由獨享的

  3. 元件級的

1. 全域性導航鉤子:

全域性導航鉤子主要有兩種鉤子:前置守衛、後置鉤子,

註冊一個全域性前置守衛:

const router = new VueRouter({ ... });
router.beforeEach((to, from, next) => {
    // do someting
});

這三個引數 to 、from 、next 分別的作用:

  1. to: Route,代表要進入的目標,它是一個路由物件

  2. from: Route,代表當前正要離開的路由,同樣也是一個路由物件

  3. next: Function,這是一個必須需要呼叫的方法,而具體的執行效果則依賴 next 方法呼叫的引數

    • next():進入管道中的下一個鉤子,如果全部的鉤子執行完了,則導航的狀態就是 confirmed(確認的)
    • next(false):這代表中斷掉當前的導航,即 to 代表的路由物件不會進入,被中斷,此時該表 URL 地址會被重置到 from 路由對應的地址
    • next(‘/’) 和 next({path: ‘/’}):在中斷掉當前導航的同時,跳轉到一個不同的地址
    • next(error):如果傳入引數是一個 Error 例項,那麼導航被終止的同時會將錯誤傳遞給 router.onError() 註冊過的回撥

注意:next 方法必須要呼叫,否則鉤子函式無法 resolved

對於全域性後置鉤子:

router.afterEach((to, from) => {
    // do someting
});

不同於前置守衛,後置鉤子並沒有 next 函式,也不會改變導航本身

2. 路由獨享的鉤子

顧名思義,即單個路由獨享的導航鉤子,它是在路由配置上直接進行定義的:

cont router = new VueRouter({
    routes: [
        {
            path: '/file',
            component
: File, beforeEnter: (to, from ,next) => { // do someting } } ] });

至於他的引數的使用,和全域性前置守衛是一樣的

3. 組建內的導航鉤子

元件內的導航鉤子主要有這三種:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave。他們是直接在路由元件內部直接進行定義的

我們看一下他的具體用法:

const File = {
    template: `<div>This is file</div>`,
    beforeRouteEnter(to, from, next) {
        // do someting
        // 在渲染該元件的對應路由被 confirm 前呼叫
    },
    beforeRouteUpdate(to, from, next) {
        // do someting
        // 在當前路由改變,但是依然渲染該元件是呼叫
    },
    beforeRouteLeave(to, from ,next) {
        // do someting
        // 導航離開該元件的對應路由時被呼叫
    }
}

需要注意是:

beforeRouteEnter 不能獲取元件例項 this,因為當守衛執行前,元件例項被沒有被創建出來,剩下兩個鉤子則可以正常獲取元件例項 this

但是並不意味著在 beforeRouteEnter 中無法訪問元件例項,我們可以通過給 next 傳入一個回撥來訪問元件例項。在導航被確認是,會執行這個回撥,這時就可以訪問元件例項了,如:

beforeRouteEnter(to, from, next) {
    next (vm => {
        // 這裡通過 vm 來訪問元件例項解決了沒有 this 的問題
    })
}

注意,僅僅是 beforRouteEnter 支援給 next 傳遞迴調,其他兩個並不支援。因為歸根結底,支援回撥是為了解決 this 問題,而其他兩個鉤子的 this 可以正確訪問到元件例項,所有沒有必要使用回撥

最後是完整的導航解析流程:

  1. 導航被觸發
  2. 在失活的元件裡呼叫離開守衛
  3. 呼叫全域性的 beforeEach 守衛
  4. 在重用的元件裡呼叫 beforeRouteUpdate 守衛
  5. 在路由配置裡呼叫 beforEnter
  6. 解析非同步路由元件
  7. 在被啟用的元件裡呼叫 beforeRouteEnter
  8. 呼叫全域性的 beforeResolve 守衛
  9. 導航被確認
  10. 呼叫全域性的 afterEach 鉤子
  11. 觸發 DOM 更新
  12. 在建立好的例項呼叫 beforeRouteEnter 守衛中傳給 next 的回撥函式