Vue同一路由跳转页面不刷新解决方案及注意事项
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
通过console我们可以看到先执行的是beforeRouteEnter
然后才是mounted
,也就是路由的生命周期优先于组件的生命周期。我们想要的toast在showInfo
方法得到执行。
我们接下来再做几个路由跳转相关的测试。
0.初始态,直接刷新goNext
1.点击“跳转至自身”后url的链接地址变了,只有watch
里面的回调执行了,其它的都没有
所以我们想要出现toast,就只能在watch里面调用
showInfo
了。
2.如果再点击“跳转至goBack”会有什么效果呢?
总体先后顺序肯定是先goNext再goBack。然后依然是路由的生命周期优先于组件的生命周期,并且是老的先销毁,新的再加载。
3.跳转到goBack页面,我们在点击“返回”呢?
效果和上面的第2个一样(废话)
“同一页面跳转,路由变了但是页面不刷新”这个“问题”我们只能通过watch路由来实现么?
有时我们有很多这样的同一页面再次跳转需求怎么办,给每个页面加上watch,然后把mounted
里面的内容也在一个方法里面,然后再mounted
里面调用该方法,并且在watch里面也调用?这当然没问题,有时不是太多了想偷点懒吗,怎么办?
这就需要用到key了
怎么弄?
<router-view :key="$route.fullPath"></router-view>
因为我们在加入了query并且里面的info是使用的时间戳,所以每次fullPath都不一样
为了对比我们可以再加入一个不带时间戳的跳转
goNextWithoutTimestamp() {
this.$router.push({
path: '/goNext',
})
},
4.当我们点击“跳转至自身不带时间戳”时,结果是这样,有这种同一路由多次跳转的网友应该不陌生。
因为路由地址完全一样,fullPath也是一样的,上的key其实也没有任何帮助。
5.但是如果这是我们再点击之前的“跳转至自身”会有什么结果呢?
我们可以看到组件的生命周期确实执行了,但是路由的生命周期没有执行了,比如beforeRouteLeave
,那样我们想在组件里面的路由钩子里面进行一些阻止跳转的逻辑就不行了。
那我们再进一步,加上全局的路由钩子看看有什么效果,全局的还会执行吗?
我们先进行这样的改动
我们先重新执行下前面第4、5个示例。
重试4
重试5
通过重试4、5可以发现跟4、5不同的是全局的路由钩子还是会如期执行的。
接下来我们再重试下前面的第0、1、2、3个示例吧。加上了全局路由钩子和:key="$route.fullPath"
重试0
重试1
重试2
重试3
总结一下,就是用时间戳传给路由的query,这样就会导致$route.fullPath
不一样,然后我们再在router-view
上配合key
就实现了Vue同一路由能够跳转页面,但是这个方案并不完美,它也是有缺点的,缺点就是组件内的路有生命周期beforeRouteLeave
不执行了,我们通常在这个周期里面做一些例如编辑文章时突然要跳走,可以来提示是否保存草稿的事情。
- 分类:
- Web前端
相关文章
AngularJS的controllerAs常见用法
我们一般用controllerAs多半是因为要用到我们的controller里面的数据,比如获取一个名叫cells.json,里面包含了所有手机的概况,我们需要获取这些数据以便ng-repeate它, 阅读更多…
本站301重定向wordpress固定链接
因为不想在用类似www.daozhao.com/82.html一样的固定链接了,感觉用别名对网站的SEO更好点,再加上用别名了我们可以通过url初步判断文章的内容,于是我站改成用别名了,原www.da 阅读更多…