1). 问题:
编程式路由跳转到当前路径且参数没有变化时会抛出 NavigationDuplicated 错误
2). 原因分析:
vue-router3.1.0之后, 引入了push()的promise的语法, 如果没有通过参数指定回调函数就返回一个promise来指定成功/失败的回调, 且内部会判断如果要跳转的路径和参数都没有变化, 会抛出一个失败的promise
3). 解决:
方案1: 在进行跳转时, 指定跳转成功的回调函数或catch错误
// catch()处理错误
this.$router.push(`/search/${this.keyword}`).catch(() => {})
// 指定成功的回调函数
this.$router.push(`/search/${this.keyword}`, () => {})
// 指定失败的回调函数
this.$router.push(`/search/${this.keyword}`, undefined, () => {})
方案2: 修正Vue原型上的push和replace方法
// 缓存原型上的push函数
const originPush = VueRouter.prototype.push
const originReplace = VueRouter.prototype.replace
// 给原型对象上的push指定新函数函数
VueRouter.prototype.push = function (location, onComplete, onAbort) {
// 判断如果没有指定回调函数, 通过call调用源函数并使用catch来处理错误
if (onComplete===undefined && onAbort===undefined) {
return originPush.call(this, location, onComplete, onAbort).catch(() => {})
} else { // 如果有指定任意回调函数, 通过call调用源push函数处理
originPush.call(this, location, onComplete, onAbort)
}
}
VueRouter.prototype.replace = function (location, onComplete, onAbort) {
if (onComplete===undefined && onAbort===undefined) {
return originReplace.call(this, location, onComplete, onAbort).catch(() => {})
} else {
originReplace.call(this, location, onComplete, onAbort)
}
}