通过this.$router.push跳转同一路由页面只会刷新一次的问题怎么解决

一、原因

Vue Router默认会认为同一路由之间的跳转是相同路由的导航,所以不会触发组件的重新渲染。

当我们连续重复跳转相同的路由导航时就会报错如:

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

我们可以手动捕获错误:在this.$router.pushPromise链中添加一个.catch()来捕获这个错误并处理它,例如给出一个警告。

this.$router.push('/homePage').catch(err => {
  if (err.name !== 'NavigationDuplicated') {
    throw err;
  } else {
    console.log('NavigationDuplicated error caught:', err);
    // 在这里处理错误,例如给出警告
  }
});

在实际开发中,我们经常会在路由文件中重写push方法,使其在导航重复错误时返回错误对象。

const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push (location) {
  return originalPush.call(this, location).catch(err => err)
}
Vue.use(VueRouter)

当多个导航菜单用相同的路由时也会出现这种问题

二、解决方法

1、使用watch监听route对象

在组件中使用watch监听route对象的变化,当路由发生变化时手动触发组件的更新

watch: {
  $route(to, from) {
    if (to.path === from.path) {
      // 如果目标路由和来源路由的路径相同,则强制刷新页面
      this.$router.go();
    }
  }
}

2、使用key属性强制组件重新渲染

在需要刷新的组件中,通过设置标签的key属性为路由路径,以确保每次路由变化时都会强制重新渲染组件

<router-view :key="$route.fullPath" />

这样会导致所有路由组件都在每次路由变化时都重新渲染,这可能不符合实际需求,尤其是对于那些不需要强制刷新的路由组件而言。在这种情况下,我们需要一种更精细化的方式来控制路由组件的刷新行为。

如:条件性地使用<router-view>的key属性

① 在路由配置中,为每个需要强制刷新的路由组件设置一个唯一的名称或者特定参数

const routes = [
  { path: '/foo', name: 'Foo', component: FooComponent },
  { path: '/bar/:id', name: 'Bar', component: BarComponent },
  // 其他路由配置...
];

②在路由组件的模板中,使用路由的 name 或者特定参数的值作为 <router-view> key 属性值。

<!-- 根据路由组件的名称作为 key -->
<router-view :key="$route.name" />

<!-- 或者根据某个特定参数的值作为 key -->
<router-view :key="$route.params.id" />

可以根据不同的路由组件动态地判断是否需要重新渲染,而不会影响其他不需要刷新的路由组件。

最后,使用着两种方法可以解决通过this.$router.push跳转同一路由页面只会刷新一次的问题,但它们也存在一些缺点:

  1. 性能影响
    使用watch监听$route对象或设置key属性强制组件重新渲染都会带来一定的性能开销,可能会影响页面的加载和渲染性能。
  2. 潜在的副作用
    强制重新渲染组件可能会导致一些意外的副作用,例如丢失用户输入的数据、重新触发组件生命周期钩子等。

页面强制刷新时,浏览器会重新加载整个页面,包括 JavaScript、Vue 实例以及所有组件,因此会导致所有状态都被重新初始化。比如点击导航按钮本来会根据路由匹配来给相应的菜单项添加 is-active 类,但是由于强制刷新了,这个类也被初始化了,那么导航按钮的显示没有被选中就会有问题。所以在开发中,尽量一个导航菜单对应一个路由。

暂时还没有找到好的解决办法,有其他方法的请多多指导。

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
使用this.$router.push跳转页面时,如果需要刷新页面,可以通过在App.vue组件中的router-view标签设置key值来实现。具体方法是在router-view标签中添加:key="$route.fullPath",这样当路由改变时,页面就会被刷新。另外,也可以通过监听器watch中的$route方法来实现页面刷新,具体做法是在watch中监听$route的变化,然后使用this.$router.go(0)或window.location.reload()来刷新页面。还有一种方法是在中转组件中,使用this.$router.push跳转页面之前,先调用一个方法来获取参数,在跳转时将参数作为query传递给目标页面,这样目标页面就会刷新。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [$this.router.push()更新页面](https://blog.csdn.net/weixin_45188787/article/details/124512513)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [vue之this.$router.push页面刷新问题](https://blog.csdn.net/weixin_47800450/article/details/112167359)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值