Vue中使用this.$router.push切换路由时页面不刷新的解决方法

发布时间:2023-05-23

一、原因分析

在我们平时使用Vue开发项目时,经常会使用this.$router.push切换路由,从而实现页面之间的跳转。但是,有时候我们发现切换路由后,页面并没有进行刷新,这时候我们需要先明确一下这种现象的原因。 实际上,这种现象主要是由于Vue使用了虚拟DOM这一技术所导致的。在Vue中,每当数据发生改变时,Vue会通过比较新旧虚拟DOM树的差异来更新页面,从而实现页面的动态渲染。而使用this.$router.push切换路由后,并没有触发数据的改变,因此也就没有引起页面的重新渲染。 即使我们使用watch来监听路由的改变,由于Vue的异步更新机制,也仍然不能保证watch回调函数中的代码能够在页面更新之前执行完毕。

二、解决方案

1、使用this.$router.go(0)方法刷新页面

在使用this.$router.push切换路由后,我们可以通过调用this.$router.go(0)方法来强制刷新页面。这个方法会让路由回退到当前页面,并重新加载一次页面。

// 在组件中使用this.$router.push切换路由
this.$router.push('/my-route')
// 页面不刷新,调用this.$router.go(0)方法
this.$router.go(0)

但是,使用这种方法会有以下几个缺点:

  • 如用户当前的滚动位置、表单数据等都会丢失,从用户体验上讲并不友好。
  • 由于页面被重新加载,也就导致了从服务器重新获取数据,因此会增加服务器的压力。

2、使用Vue的key特性

Vue提供了一个特性叫key,可以用来指定组件在更新时的唯一标识符。当组件的key发生改变时,Vue会销毁该组件并重新创建一个新的组件实例,从而重新渲染页面。 因此,我们可以在路由切换时,通过给<router-view>标签设置一个key,来实现页面的重新渲染。

<template>
  <div>
    <ul>
      <router-link to="/route1">Route1</router-link>
      <router-link to="/route2">Route2</router-link>
    </ul>
    <router-view :key="$route.fullPath" />
  </div>
</template>

在上述代码中,我们通过给<router-view>标签加上:key="$route.fullPath",来让Vue在更新页面时使用完整的路由路径作为key值。这样,在调用this.$router.push切换路由时,Vue就会重新渲染页面了。 需要注意的是,使用:key特性并不是解决页面不刷新的唯一方法,但是在大多数情况下,它是最为便捷和高效的方法。

3、使用watch监控$route对象

在Vue的实例中,我们可以使用watch来监听变量的改变。同样,在Vue的路由对象$route中,也有一个query变量,可以用来表示当前路由的请求参数。因此,我们可以通过watch来监控$route对象的变化,从而在路由切换时自动刷新页面。

<template>
  <div>
    <ul>
      <router-link to="/route1">Route1</router-link>
      <router-link to="/route2">Route2</router-link>
    </ul>
    <router-view />
  </div>
</template>
<script>
export default {
  watch: {
    '$route': function () {
      location.reload()
    }
  }
}
</script>

在上述代码中,我们通过使用watch来监听$route变量的改变,当$route发生变化时,我们就调用location.reload()方法来刷新页面。这种方法的优点是极为简单,但是需要注意:由于它每次刷新页面都会从服务器重新获取数据,因此需要注意性能问题。

三、小结

总的来说,使用this.$router.push切换路由时页面不刷新的问题,其根本原因在于Vue使用了虚拟DOM技术。因此,在解决这个问题时,我们需要从底层原理上入手,并结合Vue提供的key特性、watch等方法,来实现页面的重新渲染。 需要注意的是,在使用方法二和方法三时,我们应该根据具体情况来选择何时去刷新页面,以避免页面重新加载造成的性能问题。同时,在实际项目中,我们也可以结合使用这两种方法,以达到更好的页面刷新效果。