2x7 - VueRouter - 进阶 - 导航故障与重定向检查

1,379 阅读2分钟

VueRouter 基础教程系列 🎉

导航结果

路由导航的所有可能结果如下所示:

  • 正确跳转到目标页面
  • 可预知的故障
    • 导航被中断
    • 导航被取消
    • 已经处于所要导航的目标页面
  • 不可预知故障
    • 导航守卫中抛出 Error
  • 发生重定向

可预知故障

不论是声明式导航还是命令式导航,其内部都是通过命令的方式来实现路由的跳转。

命令式导航方法 push 或者是 replace 会在路由发生故障时返回一个 Promise 结果,这个 Promise 解析值是一个带有额外属性的 Error 实例,通过这些额外的属性,我们可以很方便的判断故障的类别。

如果返回结果是一个 undefine ,则说明导航被成功确认。

为了便于故障类型的判断,VueRouter 还为我们提供了两个辅助工具,分别是:

  • NavigationFailureType :故障类型的枚举值。
  • isNavigationFailure(failure[, NavigationFailureType]) :判断是否存在着指定的故障,第二个参数可省略,只判断是否存在路由故障。

先看下 NavigationFailureType 的枚举值情况:

export declare enum NavigationFailureType {
    /**
     * An aborted navigation is a navigation that failed because a navigation
     * guard returned `false` or called `next(false)`
     */
    aborted = 4,
    /**
     * A cancelled navigation is a navigation that failed because a more recent
     * navigation finished started (not necessarily finished).
     */
    cancelled = 8,
    /**
     * A duplicated navigation is a navigation that failed because it was
     * initiated while already being at the exact same location.
     */
    duplicated = 16
}

详细说明:

NavigationFailureType说明
aborted在导航守卫中返回 false 中断了本次导航。
cancelled在当前导航还没有完成之前又有了一个新的导航。比如,在等待导航守卫的过程中又调用了 router.push
duplicated导航被阻止,因为我们已经在目标位置了。

检测导航故障

{
   async navigation() {
        const failure = vm.$router.push("/about");
        if (failure) {
          //导航失败
          //辅助工具检查导航失败
          isNavigationFailure(failure);
          //辅助工具检查导航失败原因
          isNavigationFailure(failure, NavigationFailureType.aborted);
        } else {
          //导航成功
        }
    }
}

检测 cancelled 故障

import { isNavigationFailure, NavigationFailureType } from "vue-router";
//....

{
    async navigation() {
        vm.$router.push("/about").then((failure) => {
          if (failure) {
            console.log(
              isNavigationFailure(failure, NavigationFailureType.cancelled) //true
            );
          }
        });
        vm.$router.push("/test");
    }
}

不可预知故障

导航守卫抛出了一个 Error.

检查重定向

触发重定向的场景:

  • 在路由配置中使用 redirect 配置项。
  • 在导航守卫中使用 next 跳转到新的位置。

重定向会覆盖正在进行的导航。与其他返回值不同的是,重定向不会阻止导航,而是创建一个新的导航。因此,通过读取路由地址中的 redirectedFrom 属性便可以判断是否存在重定向:

await router.push('/my-profile')
if (router.currentRoute.value.redirectedFrom) {
  // redirectedFrom 是解析出的路由地址,就像导航守卫中的 to和 from
}

也可以从 $route 对象中读取 redirectedFrom