快速理解Vue路由導航守衛

概念:

“導航”表示路由正在發生變化

vue-router 提供的導航守衛主要用來通過跳轉或取消的方式守衛導航。有多種機會植入路由導航過程 中:全局的, 單個路由獨享的, 或者組件級的。

導航守衛:包括全局導航守衛和局部導航守衛

一、全局守衛

vue-router全局有三個守衛

  • router.beforeEach :全局前置守衛,進入路由之前
  • router.beforeResolve :全局解析守衛,在beforeRouteEnter調用之後調用(不常用)
  • router.afterEach :全局後置鉤子,進入路由之後

1.全局前置守衛

你可以使用 router.beforeEach 註冊一個全局前置守衛:

const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// to和from都是路由實例
// to:即將跳轉到的路由
// from:現在的要離開的路由
// next:函數
})

  • next: Function : 一定要調用該方法來 resolve 這個鉤子。執行效果依賴 next 方法的調用參數。
  • next() : 進行管道中的下一個鉤子。如果全部鉤子執行完瞭,則導航的狀態就是 confirmed (確認的)。
  • next(false) : 中斷當前的導航。如果瀏覽器的 URL 改變瞭 (可能是用戶手動或者瀏覽器後退按鈕),那麼 URL 地址會重置到 from 路由對應的地址。
  • next(‘/’) 或者 next({ path: ‘/’ }) : 跳轉到一個不同的地址。當前的導航被中斷,然後進行一個新的導航。你可以向 next 傳遞任意位置對象,且允許設置諸如 replace: true 、 name: ‘home’ 之類的選項以及任何用在 router-link to proprouter.push 中的選項。
  • next(error) : (2.4.0+) 如果傳入 next 的參數是一個 Error 實例,則導航會被終止且該錯誤會 被傳遞給 router.onError() 註冊過的回調。

註意:如果是next(‘/’) 或者 next({ path: ‘/’ }),隻要帶瞭要放行的路徑,那麼前面必須有判斷,在

什麼時候給他放行,不然他會一直循環。

2.全局解析守衛

2.5.0 新增

// 全局解析守衛 
router.beforeResolve((to,from.next) => { })

在 2.5.0+ 你可以用 router.beforeResolve 註冊一個全局守衛。這和 router.beforeEach 類似,區

別是在導航被確認之前,同時在所有組件內守衛和異步路由組件被解析之後,解析守衛就被調用。

3.全局後置鉤子

你也可以註冊全局後置鉤子,然而和守衛不同的是,這些鉤子不會接受 next 函數也不會改變導航本身:

// 全局後置鉤子
 router.afterEach((to,form) => { })

因為:afterEach被調用時,路由已經跳轉完成,所以不需要next函數

三、路由獨享的守衛

如果不想在全局配置路由的話,可以為某些路由單獨配置守衛

比如:mainpage頁面單獨配置守衛

{ 
path: '/mainpage', 
name: 'About', 
component: About, // 路由獨享守衛 
beforeEnter:(to,from,next) => {
 if(from.name === '/mainpage/about'){ alert("這是從about來的") 
   }else{
 alert("這不是從about來的") 
   }next(); // 必須調用來進行下一步操作。否則是不會跳轉的 
 }
} 
},

四、組件內的守衛

最後,你可以在路由組件內直接定義以下路由導航守衛:

  • beforeRouteEnter():進入路由前
  • beforeRouteUpdate():路由復用同一個組件時
  • beforeRouteLeave():離開當前路由時

在Product中舉個例子:

// 全局解析守衛
router.beforeResolve((to,from.next) => {
})
// 全局後置鉤子
router.afterEach((to,form) => {
})
{
path: '/mainpage',
name: 'About',
component: About,
// 路由獨享守衛
beforeEnter:(to,from,next) => {
if(from.name === '/mainpage/about'){
alert("這是從about來的")
}else{
alert("這不是從about來的")
}
next(); // 必須調用來進行下一步操作。否則是不會跳轉的
}
}
},
export default {
// 組件內守衛beforeRouteUpdate被觸發的條件是:當前路由改變,但是該組件被復用的時候。
比如說:product/orders到product/cart這個路由,都復用瞭 Product.vue 這個組件,這個時候
beforeRouteUpdate就會被觸發。可以獲取到this實例。
一個完整的導航解析流程
// 因為這個鉤子調用的時候,組件實例還沒有被創建出來,因此獲取不到this
beforeRouteEnter (to, from, next) {
console.log(to.name);
// 如果想獲取到實例的話
// next(vm=>{
// // 這裡的vm是組件的實例(this)
// });
next();
},
beforeRouteUpdate(to,from,next){
console.log(to.name, from.name);
next();
},
// 路由即將要離開的時候調用此方法
// 比如說,用戶編輯瞭一個東西,但是還麼有保存,這時候他要離開這個頁面,就要提醒他一下,還沒保
存,是否要離開
beforeRouteLeave (to, from, next) {
const leave = confirm("確定要離開嗎?");
if(leave) next() // 離開
else next(false) // 不離開
},
}

  • beforeRouteUpdate被觸發的條件是:當前路由改變,但是該組件被復用的時候。
  • 比如說:product/orders到product/cart這個路由,都復用瞭 Product.vue 這個組件,這個時候
  • beforeRouteUpdate就會被觸發。可以獲取到this實例。

五、一個完整的導航解析流程

  • 1、導航被觸發。
  • 2、在失活的組件(即將離開的頁面組件)裡調用離開守衛。 beforeRouteLeave
  • 3、調用全局的 beforeEach 守衛。
  • 4、在重用的組件裡調用 beforeRouteUpdate 守衛 (2.2+)。
  • 5、在路由配置裡調用(路由獨享的守衛) beforeEnter
  • 6、解析異步路由組件
  • 7、在被激活的組件(即將進入的頁面組件)裡調用 beforeRouteEnter
  • 8、調用全局的 beforeResolve 守衛 (2.5+)。
  • 9、導航被確認。
  • 10、調用全局的 afterEach 鉤子。所有的鉤子都觸發完瞭。
  • 11、觸發 DOM 更新。
  • 12、用創建好的實例調用 beforeRouteEnter 守衛中傳給 next 的回調函數。

到此這篇關於快速理解Vue路由導航守衛的文章就介紹到這瞭,更多相關Vue路由導航守衛內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: