切换钩子函数

最后更新于:2022-04-01 07:41:11

# 切换过程中的钩子 在切换过程中,`<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` 在合并选项时会直接被新值覆盖。
';