问题描述:重复点击导航时,控制台出现报错 ,虽然不影响功能使用,但也不能坐视不管。
解决 Vue 重复点击相同路由,出现 Uncaught (in promise) NavigationDuplicated: Avoided redundant navigation 问题 .
报错内容:
Uncaught (in promise) NavigationDuplicated: Avoided redundant navigation to current location: "/home".
浏览器控制台 · 报错截图:
   解决方案:
方案一:只需在 router 文件夹下,添加如下代码:
// src/router/index.js
Vue.use(Router)
const router = new Router({
  routes
})
 
const VueRouterPush = Router.prototype.push
Router.prototype.push = function push (to) {
  return VueRouterPush.call(this, to).catch(err => err)
}
 方案二:在跳转时,判断是否跳转路由和当前路由是否一致,避免重复跳转产生问题。
toMenu (item) {
  if (this.$route.path !== item.url) {
    this.$router.push({ path: item.url })
  }
}
 方案三:使用 catch 方法捕获 router.push 异常。
this.$router.push(route).catch(err => {
  console.log('输出报错',err)
})
 这个异常其实对程序没有什么影响。出现这个问题是因为重复点击了相同的路由引起的:编程式导航路由跳转到当前路由,参数不变,在多次执行时会抛出Uncaught (in promise) NavigationDuplicated 异常。(声明式导航不会出现这个问题)
异常出现原因
在执行$router.push() 操作时,函数返回的是promise,这里可以在打印看一下:
var a = this.$router.push({name:"search",params:{keyword:this.keyword},query:{k:this.keyword.toUpperCase()}})
console.log(a);
 
   这是因为promise需要传递一个成功/失败的回调,才能处理这个异常。
解决方案
第一个解决方案:给push方法传递相应的成功、失败回调函数,可以捕获当前的错误。
但是使用这种写法,在别的组件中使用push() 或replace() 中,还是会有类似的错误出现。
var a = this.$router.push({name:"search",params:{keyword:this.keyword},query:{k:this.keyword.toUpperCase()}},()=>{},()=>{});
console.log(a);
 第二个解决方案(推荐):
this:当前组件的实例
this.$router:是VueRouter类的一个实例。
push:是VueRouter类的一个实例。
要重写VueRouter原型对象的push方法:在router文件夹下的index.js文件中补充以下代码:
//先把VueRouter原型对象的push保存一份
const originPush = VueRouter.prototype.push
//重写push方法 
VueRouter.prototype.push = function (location,resolve,reject) {
    //调用保存的push方法
    //但是保存的push方法是挂载在window的方法 所以要通过call修改this的指向
  if(resolve&&reject){
    originPush.call(this,location,resolve,reject);
  }else{
    originPush.call(this,location,()=>{},()=>{});
  }
}
 location传的是往哪里跳转。resolve与reject是用户传的成功/失败的回调。这里注意需要用call修改originpush的上下文。
问题解决。



















