守衛:即路由觸發時,在被確認之前所要執行的函數,可以啓到本次跳轉的攔截作用,可以決定本次跳轉成功與否。
鉤子:即路由觸發時機要執行的函數,不能起到攔截組用,不能干預本次跳轉的成功與否。
一、分類
1.從調用時機來分,爲兩類:守衛、鉤子
守衛:beforeEach、beforeRouteUpdate、beforeEnter、beforeRouteEnter、beforeReslove、beforeRouteLeave
鉤子:afterEach
2.從其掛載點來分,分爲三類:全局的、路由自己的、組件內部的
全局的:befroeEach、beforeReslove、afterEach
路由自己的:beforeEnter
組件內部的:beforeRouteUpdate、beforeRouteEnter、beforeRouteLeave
二、各個調用時機
1.beforeEach:跳轉觸發後,導航confirmed之前,在此過程中,所有鉤子處於等待狀態。
2.beforeReslove:在導航confirmed之前,在所有組件內部守衛和路由守衛執行完畢之後調用。
3.afterEach:在導航confirmed之後調用。
4.beforeEnter:解析異步路由組件之前調用,值得注意的是,如果兩次路由的切換訪問的是同一個組件,只是傳遞了不同的參數,那麼beforeRouteUpdate要早於beforeEnter執行。
如果兩次路由爲同一組件,如查詢商品詳情,只是更換商品id,那將不會觸發mounted生命鉤子,這種應用場景下應把初始化數據的處理代碼放到beforeRouteUpdate鉤子中執行
5..beforeRouteUpdate:當路由組件複用時,調用。在beforeEnter之前。
6.beforeRouteEnter:路由組件解析完成以後,組件實例創建之前執行,此時並未創建組件實例,所以內部不能調用this,但其next函數可以接受一個回調函數,此函數接受一個實例參數,在導航confirmed後執行回調函數。
beforeRouterEnter(to,from,next){
next(vm=>{
console.log("此時才能訪問vue實例,即vm")
})
}
7.beforeRouteLeave:離開組件時調用,可用來做一些提示操作。
值得注意的是,除了afterEach之外,每個鉤子都接受了一個next參數,此參數爲一個函數,在鉤子內部需要我們手動調用,不調用則跳轉中斷,另外此函數可以接受一個地址字符串,表示跳轉到其他地址。
三、舉例說明調用時機
假設當前在A組件觸發超鏈接跳往B組件。路由守衛&鉤子的執行過程如下:
1.超鏈接被觸發;
2.在A組件執行beforeRouteLeave函數---(組件內部的)
3.調用beforeEach函數---(全局的)
4.如果B是複用的組件,嗲用beforeRouteUpdate函數---(組件內部的)
5.解析路由組件B前,調用beforeEnter函數---(路由的)
6.解析路由異步組件B
7.導航confirmed前調用beforeReslove函數---(全局的)
8.導航確認
9.B組件創建前調用beforeRouteEnter函數---(組件內部的)
10.調用afterEach函數---(全局的)
11.創建B組件實例,DOM更新
12.執行beforeRouteEnter的回調函數,傳入當前的B實例爲參數。
到此完成一次導航。
組件內部--全局--組件內部--路由--全局--組件內部--全局。
各個守衛&鉤子的參數,參見:https://router.vuejs.org/zh/guide/advanced/navigation-guards.html