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:故障类型,用数字表示。