# 切換過程中的鉤子
在切換過程中,`<router-view>` 組件可以通過實現一些鉤子函數來控制切換過程。這些鉤子函數包括:
- `data`
- `activate`
- `deactivate`
- `canActivate`
- `canDeactivate`
- `canReuse`
你可以在組件的 `route` 選項中實現這些函數。
``` js
Vue.component('hook-example', {
// ... other options
route: {
activate: function (transition) {
console.log('hook-example activated!')
transition.next()
},
deactivate: function (transition) {
console.log('hook-example deactivated!')
transition.next()
}
}
})
```
### 切換對象
每個切換鉤子函數都會接受一個 `transition` 對象作為參數。這個切換對象包含以下函數和方法:
- **transition.from**
一個代表將要切換到的路徑的[路由對象](../route.md)。
- **transition.to**
一個代表當前路徑的路由對象。
- **transition.next()**
調用此函數處理切換過程的下一步。
- **transition.abort([reason])**
調用此函數來終止或者拒絕此次切換。
- **transition.redirect(path)**
取消當前切換并重定向到另一個路由。
### 鉤子函數異步 resolve 規則
我們經常需要在鉤子函數中進行異步操作。在一個異步的鉤子被 resolve 之前,切換會處于暫停狀態。鉤子的 resolve 遵循以下規則:
1. 如果鉤子返回一個 Promise,則鉤子何時 resolve 取決于該 Promise 何時 resolve。[更多細節](#%E5%9C%A8%E9%92%A9%E5%AD%90%E4%B8%AD%E8%BF%94%E5%9B%9E-promise)
2. 如果鉤子既不返回 Promise,也沒有任何參數,則該鉤子將被同步 resolve。例如:
``` js
route: {
activate: function (/* 沒有參數 */) {
// 如果不返回 Promise,則同步 resolve
}
}
```
3. 如果鉤子不返回 Promise,但是有一個參數 (`transition`),則鉤子會等到 `transition.next()`, `transition.abort()` 或是 `transition.redirect()` 之一被調用才 resolve。例如:
``` js
route: {
activate: function (transition) {
// 一秒后 resolve
setTimeout(transition.next, 1000)
}
}
```
4. 在驗證類的鉤子,比如 `canActivate`, `canDeactivate` 以及[全局 beforeEach 鉤子](../api/before-each.md) 中,如果返回值是一個布爾值 (Boolean),也會使得鉤子同步 resolve。
### 在鉤子中返回 Promise
- 當在鉤子函數中返回一個 Promise 時,系統會在該 Promise 被 resolve 之后自動調用`transition.next`。
- 如果 Promise 在驗證階段被 reject,系統會調用 `transition.abort`。
- 如果 Promise 在激活階段被 resolve,系統會調用 `transition.next` 。
- 對于驗證類鉤子( `canActivate` 和 `canDeactivate` ),如果 Promise resolve 之后的值是假值( falsy value ),系統會中斷此次切換。
- 如果一個被 reject 的 Promise 拋出了未捕獲的異常,這個異常會繼續向上拋出,除非在創建路由器的時候啟用了參數 `suppressTransitionError` 。
**例子:**
``` js
// 在組件定義內部
route: {
canActivate: function () {
// 假設此 service 返回一個 Promise ,這個 Promise 被斷定后
// 的值是 `true` 或者 `false`
return authenticationService.isLoggedIn()
},
activate: function (transition) {
return messageService
.fetch(transition.to.params.messageId)
.then((message) => {
// 獲取數據后更新 data
// 組件知道此函數執行過后才會被展示出來
this.message = message
})
}
}
```
此處,我們在 `activate` 鉤子中異步的獲取數據,因為這里僅僅是做個示例;注意通常我們可以使用[ `data` 鉤子](data.md)來做這些,它會更加適合。
**提示:** 如果使用 ES6 ,可以使用參數解構( argument destructuring )使鉤子更加簡潔:
``` js
route: {
activate ({ next }) {
// when done:
next()
}
}
```
查看 vue-router 中的[高級示例](https://github.com/vuejs/vue-router/tree/dev/example/advanced)
### 鉤子合并
和組件本身的生命周期鉤子一樣,以下路由生命周期鉤子:
- `data`
- `activate`
- `deactivate`
也會在合并選項時(擴展類或是使用 mixins)被合并。舉例來說,如果你的組件本身定義了一個路由 `data` 鉤子,而這個組件所調用的一個 mixin 也定義了一個路由 `data` 鉤子,則這兩個鉤子都會被調用,并且各自返回的數據將會被最終合并到一起。
需要注意的是,驗證類鉤子,比如 `canActivate`, `canDeactivate` 和 `canReuse` 在合并選項時會直接被新值覆蓋。
- vue
- 官方教程
- 起步
- 安裝
- 概述
- Vue 實例
- Class 與 Style 綁定
- 數據綁定語法
- 條件渲染
- 列表渲染
- 表單控件綁定
- 組件
- 計算屬性
- 自定義指令
- 自定義過濾器
- 方法與事件處理器
- 混合
- 插件
- 過渡
- 深入響應式原理
- 對比其它框架
- 構建大型應用
- API
- vue-router
- 安裝
- 基本用法
- 嵌套路由
- 路由對象和路由匹配
- 具名路徑
- 路由配置項
- router-view
- v-link
- 切換控制流水線
- 切換鉤子函數
- data
- activate
- deactivate
- canActivate
- canDeactivate
- canReuse
- API
- 路由實例屬性
- router.start
- router.stop
- router.map
- router.on
- router.go
- router.replace
- router.redirect
- router.alias
- router.beforeEach
- router.afterEach
- 文章
- VUE.JS: A (RE)INTRODUCTION
- 源碼
- 表單控件綁定