Vue Router 导航故障

导航故障

导航故障,或者叫导航失败。

当使用 router-link 组件时,Vue Router 会自动调用 router.push 来触发一次导航。 虽然大多数链接的预期行为是将用户导航到一个新页面,但也有少数情况下用户将留在同一页面上:

  • 用户已经位于他们正在尝试导航到的页面
  • 一个导航守卫通过调用 next(false) 中断了这次导航
  • 一个导航守卫抛出了一个错误,或者调用了 next(new Error())

当使用 router-link 组件时,这些失败都不会打印出错误。然而,如果你使用 router.push 或者 router.replace 的话,可能会在控制台看到一条 "Uncaught (in promise) Error" 这样的错误,后面跟着一条更具体的消息。让我们来了解一下如何区分导航故障。

在 v3.2.0 中,可以通过使用 router.push 的两个可选的回调函数:onComplete 和 onAbort 来暴露导航故障。从版本 3.1.0 开始,router.push 和 router.replace 在没有提供 onComplete/onAbort 回调的情况下会返回一个 Promise。这个 Promise 的 resolve 和 reject 将分别用来代替 onComplete 和 onAbort 的调用。

检测导航故障

导航故障是一个Error实例附带一些额外属性,要检查一个错误是否来自于路由器,可使用isNavigationFailure函数。

举个栗子🍓:

当前页面路径为'/1',导航仍然要跳转到'/1',这时就会出现导航故障。

isNavigationFailure

向isNavigationFailure方法传入chatch回调返回的导航故障实例,以及某个导航故障类型,判断导航故障是否属于这个类型,符合条件则做处理。

只传第一个参数,则只会检查error实例是不是导航故障。

两个参数都传,不但检查是否是导航故障,还可以检查具体是哪种类型的导航故障。

this.$router.push('/1').catch(failure => {
  if (isNavigationFailure(failure, NavigationFailureType.duplicated)) {
    console.log(failure.type)
  }
})

要注意的是,isNavigationFailure方法和NavigationFailureType类需要引入。

import VueRouter from 'vue-router'

const {isNavigationFailure, NavigationFailureType} = VueRouter

使用官方引入方式是可以正常运行的,但如果是下面这种引入写法:

import {NavigationFailureType} from 'vue-router'
import {isNavigationFailure} from "vue-router/src/util/errors";

会报错的。

底层代码:

static isNavigationFailure: (
  error: any,
  type?: number
) => error is NavigationFailure

从源代码可以看出来,箭头函数检查这个error错误是不是一个导航故障。

NavigationFailure

export interface NavigationFailure extends Error {
  to: Route
  from: Route
  type: number
}

从上面可以看出,导航故障实例还是一个Error实例,所以有Error自带的name、message、stack属性,另外又附加了一些额外属性to、from、type

NavigationFailureType

导航故障类型。

帮助开发者来区分不同类型的导航故障。

  • redirected  在导航守卫找那个调用next(newLocation)重定向到了其他地方
  • aborted  在导航守卫中调用了next(false)中断了本次导航
  • cancelled  在当前导航还没有完成之前又有了一个新的导航
  • duplicated  导航被阻止,因为已经在目标位置
static NavigationFailureType: {
  [k in keyof typeof NavigationFailureType]: NavigationFailureType
}

再往下:

export enum NavigationFailureType {
  redirected = 2,
  aborted = 4,
  cancelled = 8,
  duplicated = 16
}

导航故障的属性

to、from:这次失败的导航的当前位置和目标位置。在所有情况下,to和from都是规范化的路由位置。

type:故障类型,用数字表示。

posted @ 2021-10-18 18:01  慕斯星球  阅读(968)  评论(0)    收藏  举报