首页 > 编程语言 >Vue编程式路由跳转多次执行报错

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

时间:2025-01-23 17:59:44浏览次数:3  
标签:Vue 报错 originalPush VueRouter 跳转 push router 路由

文章目录

问题描述

在使用 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 方法,能够高效解决编程式导航重复跳转的警告问题。此方法不仅全局生效,还保持了代码的简洁性。

标签:Vue,报错,originalPush,VueRouter,跳转,push,router,路由
From: https://blog.csdn.net/weixin_44283682/article/details/145327544

相关文章

  • vue3中元素盒子尺寸变化时的问题
    sizeDirect.js//此案例可以作为Vue自定义指令的参考,实现元素尺寸变化的监听,并执行回调函数。//注意:此案例仅供参考,具体业务场景需要根据实际情况进行修改。constmap=newWeakMap()//弱引用,可以被垃圾回收机制回收,可以用来保存DOM节点,不容易造成内存泄漏consto......
  • 在使用prism的region跳转时,出现The region manager does not contain the MainViewReg
    在做新项目时,把原来的旧项目拷过来进行重构,上一个项目进行region填充是没有问题的,这次再次进行测试出现了这样的问题,于是在网上寻找答案。错误给出来的很明显,regionManager没有一个叫做MainViewRegionName的区域,想当然的就手动添加,进行刷新,这种方法参考Prism区域异常问题分析(......
  • Vue.js 渐进式增强:如何逐步为传统项目注入活力
    Vue.js是一个渐进式框架,这意味着你可以将它逐步引入到现有项目中,而无需彻底重构。渐进式增强特别适合那些已经在使用传统服务器渲染框架(如PHP、Django、Laravel)的项目,为它们增加动态交互功能。本篇教程将介绍如何将Vue.js无缝集成到传统项目中。什么是渐进式增强?渐进式......
  • 初级黑客入门之sql注入报错分享(mssql+mysql),黑客技术零基础入门到精通实战教程!
    mysql溢出类bigint当超过mysql的整形的时候,就会导致溢出,mysql可能会将错误信息带出。这里user()是字母默认为0取反以后+1可能就会导致异常。报错特征BIGINTUNSIGNEDvalueisoutofrangein不需要函数,直接让他报错出来select%20(~(select%20\*%20from(select%2......
  • vue template 转 jsx 写法及TS类型应用
    vue的响应式数据+jsx开发体验简直不要太好,心智负担确实小,简直完爆react(纯属个人暴论),不足的地方就是生态了,这点确实比不过react。本文更侧重于TS类型的写法,毕竟初次接触vuejsx时,实在对其TS类型声明很不顺手。要说vue模板语法哪些API不能在jsx中使用,也就是一些......
  • JAVA实战开源项目:在线旅游网站(Vue+SpringBoot) 附源码
    本文项目编号T025,文末自助获取源码\color{red}{T025,文末自助获取源码}......
  • JAVA实战开源项目:社区团购系统(Vue+SpringBoot) 附源码
    本文项目编号T024,文末自助获取源码\color{red}{T024,文末自助获取源码}......
  • JAVA实战开源项目:课程作业管理系统(Vue+SpringBoot) 附源码
    本文项目编号T023,文末自助获取源码\color{red}{T023,文末自助获取源码}......
  • Vue 性能优化:从渲染优化到代码分割的全面指南
    目录Vue极速入门第12节:Vue性能优化:从渲染优化到代码分割的全面指南引言1.减少不必要的渲染:`v-once`与`v-memo`的使用1.1什么是渲染优化?1.2使用`v-once`指令1.3使用`v-memo`指令1.4`v-once`与`v-memo`的对比2.懒加载与代码分割:路由懒加载与动态导入......
  • paddleocr报错解决方案汇总
    一、安装注意事项python不要超过10,尽量选8/9/10二、快速开始参考官方文档:https://paddlepaddle.github.io/PaddleOCR/main/ppstructure/quick_start.html#221一般都要带方向识别,这里复制其中一段代码,防止官网挂掉importosimportcv2frompaddleocrimportPPStructure,dr......