You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue路由报错NavigationDuplicated:切换Workspace重载页面带新参数失败

Vue路由跳转同路由不同参数触发NavigationDuplicated错误的解决办法

问题场景

监听workspace状态变化时,通过$router.push跳转到同路由但不同参数的路径(如从/profile/c/123切换至/profile/p/321),控制台抛出错误:

Uncaught (in promise) NavigationDuplicated: Avoided redundant navigation to current location: "previous location".

当前实现代码:

@Watch('workspace')
onWorkspaceChanged(o: Workspace, n: Workspace){
  if(o.type === n.type && o.id === n.id) return;
  this.$router.push({name: this.$route.name as string, params: {id: `${n.id}`, type: `${ n.type == WorkspaceType.COMPANY ? COMPANY : PERSON }`}});
}

原因

Vue Router 3.x+版本中,默认会将同路由名称但参数不同的跳转判定为重复导航——内部通过fullPath判断是否重复,但实际我们需要更新参数并重新渲染页面。

解决方案

1. 捕获push的Promise异常

$router.push返回Promise,直接捕获重复导航的错误即可:

@Watch('workspace')
onWorkspaceChanged(o: Workspace, n: Workspace){
  if(o.type === n.type && o.id === n.id) return;
  this.$router.push({
    name: this.$route.name as string,
    params: {
      id: `${n.id}`,
      type: `${ n.type == WorkspaceType.COMPANY ? COMPANY : PERSON }`
    }
  }).catch(err => {
    // 仅忽略重复导航错误,其他错误正常上报
    if (err.name !== 'NavigationDuplicated') {
      console.error(err);
    }
  });
}

2. 用$router.replace替代push

如果不需要保留当前路由的历史记录,使用replace替换当前历史条目,不会触发重复导航错误:

@Watch('workspace')
onWorkspaceChanged(o: Workspace, n: Workspace){
  if(o.type === n.type && o.id === n.id) return;
  this.$router.replace({
    name: this.$route.name as string,
    params: {
      id: `${n.id}`,
      type: `${ n.type == WorkspaceType.COMPANY ? COMPANY : PERSON }`
    }
  });
}

3. 全局处理重复导航错误

项目多处需要处理时,在路由初始化文件中全局修改push和replace方法:

// router/index.js
import VueRouter from 'vue-router';

// 重写push方法
const originalPush = VueRouter.prototype.push;
VueRouter.prototype.push = function push(location) {
  return originalPush.call(this, location).catch(err => err);
};

// 重写replace方法
const originalReplace = VueRouter.prototype.replace;
VueRouter.prototype.replace = function replace(location) {
  return originalReplace.call(this, location).catch(err => err);
};

4. 强制组件重新渲染

给路由视图绑定key为$route.fullPath,参数变化时组件会重新创建:

<!-- 根组件或父组件模板中 -->
<router-view :key="$route.fullPath"></router-view>

也可以在目标组件内监听路由变化,手动处理业务逻辑:

@Watch('$route')
onRouteChanged(to, from) {
  // 参数变化后重新请求数据或更新状态
}

内容的提问来源于stack exchange,提问作者Vladislav Uvarov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 19:05:24