欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > Vue编程式路由跳转多次执行报错

Vue编程式路由跳转多次执行报错

2025/5/17 11:10:51 来源:https://blog.csdn.net/weixin_44283682/article/details/145327544  浏览:    关键词:Vue编程式路由跳转多次执行报错

文章目录

      • 问题描述
      • 路由跳转的两种形式
      • 问题原因
      • 解决方案
        • 1. 传递回调函数
        • 2. 重写 `push` 方法(推荐)
      • 代码实现细节解析
        • 1. 为什么不能直接使用 `this.originalPush()`?
        • 2. `this` 的指向是什么?
        • 3. `call(this)` 的作用
        • 4. 异常捕获的意义
      • 其他注意事项
      • 总结

问题描述

在使用 Vue.js 的 vue-router 进行编程式路由跳转时,如果多次执行跳转到当前路由(参数不变),会抛出 NavigationDuplicated 的警告错误。这种错误通常发生在用户频繁点击按钮或执行某些操作时,导致多次触发相同的路由跳转。

路由跳转的两种形式

  1. 声明式导航:通过 <router-link> 标签进行导航,vue-router 底层已经处理好了重复导航的问题,因此不会出现此类警告。
  2. 编程式导航:通过 this.$router.pushthis.$router.replace 方法进行导航,可能会出现 NavigationDuplicated 警告。

问题原因

vue-router 3.5.3 及以上版本中,pushreplace 方法返回一个 Promise。如果多次执行相同的路由跳转,vue-router 会检测到重复导航,并抛出 NavigationDuplicated 警告。这是为了提醒开发者避免不必要的路由跳转,从而优化应用性能。


解决方案

1. 传递回调函数

通过给 push 方法传递成功和失败的回调函数,可以捕获到当前错误,从而避免警告。

this.$router.push({name: "search",params: { keyword: this.keyword },query: { k: this.keyword.toUpperCase() }},() => {}, // 成功回调(空函数)() => {}  // 失败回调(空函数)
);

缺点

  • 治标不治本,其他组件中仍需重复添加回调函数。
  • 代码冗余,维护成本高。
2. 重写 push 方法(推荐)

通过全局重写 VueRouter 原型上的 push 方法,彻底解决重复导航问题。

// 保存原始的 push 方法
const originalPush = VueRouter.prototype.push;// 重写 push 方法
VueRouter.prototype.push = function push(location, onResolve, onReject) {if (onResolve || onReject) {// 若用户手动传递了回调函数,直接调用原始方法return originalPush.call(this, location, onResolve, onReject);}// 若未传递回调函数,捕获 Promise 异常return originalPush.call(this, location).catch(err => err);
};

优点

  • 一劳永逸,所有组件中均生效。
  • 减少代码重复,提升可维护性。

代码实现细节解析

1. 为什么不能直接使用 this.originalPush()
  • 作用域问题
    originalPush 是一个通过 const 定义的变量,保存了原始 push 方法的引用。
    它并不属于 VueRouter 实例的成员属性,因此在重写的 push 方法中,this(指向 VueRouter 实例)无法直接访问 originalPush
    若尝试调用 this.originalPush(),会导致 undefined is not a function 错误。

  • 正确调用方式
    必须通过 originalPush.call(this, ...) 显式绑定 this,确保原始方法在 VueRouter 实例的上下文中执行。

2. this 的指向是什么?
  • 在重写的 push 方法中,this 指向 调用该方法的 VueRouter 实例
    例如,当组件中调用 this.$router.push() 时:
    • this.$routerVueRouter 类的实例。
    • 因此,重写后的 push 方法中的 this 即为该实例。
3. call(this) 的作用
  • 绑定上下文
    call 方法用于显式指定函数执行时的 this 值。
    若直接调用 originalPush(location),原始 push 方法中的 this 会指向全局对象(如 windowundefined),导致路由操作失败。

  • 类比解释
    可以理解为“借用”原始方法的能力,但明确告诉它操作发生在当前 VueRouter 实例的上下文中,类似于使用他人的工具时指定工作台。

4. 异常捕获的意义
  • 通过 .catch(err => err) 捕获 Promise 异常,避免未处理的 NavigationDuplicated 错误抛出。
  • 这样即使重复导航,错误会被静默处理,不会影响用户体验。

其他注意事项

  • 路由参数变化:若跳转时参数不同(如 keyword 改变),vue-router 不会视为重复导航。需确保参数传递正确。
  • 性能优化:减少不必要的路由跳转,可提升应用性能和响应速度。

总结

通过重写 VueRouter 原型上的 push 方法,能够高效解决编程式导航重复跳转的警告问题。此方法不仅全局生效,还保持了代码的简洁性。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词