Vue同一路由跳转页面不刷新解决方案及注意事项

1,104 阅读1分钟

转载自道招网,原文地址Vue同一路由跳转页面不刷新解决方案及注意事项

默认情况跳转至同一个路由地址(path相同,即使params或者query不同也算同一个)的话,只是浏览器url变了,其它是不会发生任何变化,这就是网友常说的“同一页面跳转,路由变了但是页面不刷新”。 我们可以写两个测试页面

// goNext.vue
<template>
  <section>
    <button @click="goNext">跳转至自身</button>
    <button @click="goBack">跳转至goBack</button>
  </section>
</template>
<script>
  export default {
    name: 'goNext',
    mounted() {
      console.log('组件生命周期 mounted', 'goNext');
      this.showInfo();
    },
    beforeDestroy() {
      console.log('组件生命周期 beforeDestroy-> ', 'goNext');
    },
    beforeRouteEnter(to, from, next) {
      console.log('路由生命周期 beforeRouteEnter-> ', 'goNext');
      next();
    },
    beforeRouteLeave(to, from, next) {
      console.log('路由生命周期 beforeRouteLeave-> ', 'goNext');
      next();
    },
    methods: {
      goNext() {
        this.$router.push({
          path: '/goNext',
          query: {
            info: Date.now(),
          }
        })
      },
      goBack() {
        this.$router.push('goBack')
      },
      showInfo() {
        const info = this.$route.query.info || 'Default';
        this.$message.info(info);
      },
    },
    watch: {
      '$route'(to) {
        console.log('watch $route', to.query.info, to);
      },
    }
  }
</script>

// goBack.vue
<template>
  <section>
    <button @click="goBack">退回</button>
  </section>
</template>
<script>
  export default {
    name: 'goBack',
    mounted() {
      console.log('组件生命周期 mounted', 'goBack');
    },
    beforeDestroy() {
      console.log('组件生命周期 beforeDestroy-> ', 'goBack');
    },
    beforeRouteEnter(to, from, next) {
      console.log('路由生命周期 beforeRouteEnter-> ', 'goBack');
      next();
    },
    beforeRouteLeave(to, from, next) {
      console.log('路由生命周期 beforeRouteLeave-> ', 'goBack');
      next()
    },
    methods: {
      goBack() {
        this.$router.go(-1);
      },
    }
  }
</script>

直接进入/goNext file

通过console我们可以看到先执行的是beforeRouteEnter然后才是mounted,也就是路由的生命周期优先于组件的生命周期。我们想要的toast在showInfo方法得到执行。

我们接下来再做几个路由跳转相关的测试。 0.初始态,直接刷新goNext file

1.点击“跳转至自身”后url的链接地址变了,只有watch里面的回调执行了,其它的都没有 file 所以我们想要出现toast,就只能在watch里面调用showInfo了。

2.如果再点击“跳转至goBack”会有什么效果呢? file

总体先后顺序肯定是先goNext再goBack。然后依然是路由的生命周期优先于组件的生命周期,并且是老的先销毁,新的再加载。

3.跳转到goBack页面,我们在点击“返回”呢? file 效果和上面的第2个一样(废话)

**“同一页面跳转,路由变了但是页面不刷新”**这个“问题”我们只能通过watch路由来实现么? 有时我们有很多这样的同一页面再次跳转需求怎么办,给每个页面加上watch,然后把mounted里面的内容也在一个方法里面,然后再mounted里面调用该方法,并且在watch里面也调用?这当然没问题,有时不是太多了想偷点栏吗,怎么办?

这就需要用到key了

怎么弄?

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

因为我们在加入了query并且里面的info是使用的时间戳,所以每次fullPath都不一样

为了对比我们可以再加入一个不带时间戳的跳转

goNextWithoutTimestamp() {
	this.$router.push({
		path: '/goNext',
	})
},

4.当我们点击“跳转至自身不带时间戳”时,结果是这样,有这种同一路由多次跳转的网友应该不陌生。 file

因为路由地址完全一样,fullPath也是一样的,上的key其实也没有任何帮助。

5.但是如果这是我们再点击之前的“跳转至自身”会有什么结果呢? file

我们可以看到组件的生命周期确实执行了,但是路由的生命周期没有执行了,那样我们想在组件里面的路由钩子里面进行一些阻止跳转的逻辑就不行了。

那我们再进一步,加上全局的路由钩子看看有什么效果,全局的还会执行吗? 我们先进行这样的改动 file

我们先重新执行下前面第4、5个示例。 重试4 file 重试5 file 通过重试4、5可以发现跟4、5不同的是全局的路由钩子还是会如期执行的。

接下来我们再重试下前面的第0、1、2、3个示例吧。加上了全局路由钩子和:key="$route.fullPath" 重试0 file 重试1 file 重试2 file 重试3 file

最新内容欢迎访问原文Vue同一路由跳转页面不刷新解决方案及注意事项