Whidy Writes

Vue Router的Push方法报错NavigationDuplicated: Navigating to current location

发布于:(更新于:

最近使用 Vue Router 的 Push 方法,针对同一个路径的不同参数的页面进行导航的时候就会报错 NavigationDuplicated: Navigating to current location ,很纳闷,我们来看看是怎么回事吧。

这个 Vue Router 报错 NavigationDuplicated: Navigating to current location 的问题我印象中以前是没有遇到过的,查了些资料,原来 Vue Router 在 3.1.x 版本后就有了,而且是一年前。

而相对完整的解决方案出自No stacktrace on NavigationDuplicated error #2881

你可以给你要 push 的路径加一个空的错误捕获回调,例如:

router.push('/location').catch(err => {})

而全局修改则可以通过修改原有的 push 方法,例如:

import Router from 'vue-router' const originalPush = Router.prototype.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) }

这个问题就算解决了,那么深究一下,这个方案究竟好不好?

其实对于 Vue 框架,我的理解一直是做小型应用,至少他最早要解决的就是用户交互体验增强,一般来说切换大量参数来实现页面内容变更的逻辑就有些不合理(如果是少量参数,可以使用动态路由而不应该用 query);另一方面,使用 Vue 应用本身就不应该有重载带有大量参数的页面来渲染对应数据的页面,本身设计就是无状态的,虽然可以通过 Vuex 结合 Cookies/Storage 来实现。但是我个人觉得这是偏离初衷的。

说了堆废话,结果还是需要曲线救国的各种奇怪解决办法,然而,对于需要大量 query 参数的应用,我个人觉得还是使用 SSR 渲染框架会好些,哪怕是传统的 JSP/PHP 框架。

最后,关于这个问题,其实在 Vue.js 的 RFCS 中也有记录,请参阅0033-router-navigation-failures.md,或许在未来的 Vue Router 版本中(Maybe v4)会改进这个问题。

  • Expose NavigationFailureType and isNavigationFailure in vue-router@3 so that Navigation Failures can be told apart from regular Errors.
  • afterEach and onError are relatively simple to migrate, most of the time they are not used many times either.
  • router.push doesn't reject when navigation fails anymore. Any code relying on catching an error should await the promise result instead.
avatar

whidy

一名爱折腾的前端开发工程师,喜欢打篮球和分享 ฅʕ•̫͡•ʔฅ