1、场景描述

最近在工作的nuxt项目中,使用vue-router替代nuxt的默认路由,这样使路由关系更明显,也更好调整,再就是可以使用vue-router的编程式导航,进行路由跳转。然后,问题就出现了,在使用this.$router.push()this.$router.replace 进行路由跳转时,有时候会报 Uncaught (in promise)Error: Navigation cancelled from "/" to "/1" with a new navigation这种错误,但是使用声明式导航<router-link>的时候却不会报错,令人头秃。

在这里插入图片描述

2、定位问题

经过在网上查询前辈们发布的资料,最终得出结论:该错误是因为vue-router的内部没有对编程式导航进行catch处理,所以在使用this.$router.push()this.$router.replace 进行路由跳转时,往同一地址跳转时或者在跳转的 mounted/activated 等函数中再次向其他地址跳转时会出现报错。但是在3.1.0版本及更高版本中,页面在跳转路由控制台会报Uncaught (in promise)的问题,push和replace方法会返回一个promise, 你可能在控制台看到未捕获的异常。
声明式导航之所以不会出现这种问题,是因为vue-router在内部已经做了相关处理。

3、解决方案

在路由的配置文件中:如 router.js 或 router/index.js ,增加如下配置:

// 基本配置
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)

// 解决报错
const originalPush = Router.prototype.push
const originalReplace = Router.prototype.replace
// 针对 push 方法
Router.prototype.push = function push (location, onResolve, onReject) {
  if (onResolve || onReject) return originalPush.call(this, location, onResolve, onReject)
  return originalPush.call(this, location).catch(err => err)
}
// 针对 replace 方法
Router.prototype.replace = function push (location, onResolve, onReject) {
  if (onResolve || onReject) return originalReplace.call(this, location, onResolve, onReject)
  return originalReplace.call(this, location).catch(err => err)
}
Logo

基于 Vue 的企业级 UI 组件库和中后台系统解决方案,为数万开发者服务。

更多推荐