需求是:a->b->c
a页面和b页面都在前一个页面后退回来的时候保持之前离开页面时滚动条的位置
因我的项目不止三个页面,并且有的页面不需要保持状态 所以我使用了路由元信息来判断页面是否需要保持状态
首先在路由里添加keepAlive 为 true时页面需要保持状态 又因为a、b页面只有当他的前一个页面后退回来才需要保持而别的页面进入a、b页面是不需要保持的 所以又添加了isBack来判断是否需要保持数据
{
path: 'home',
component: () => import('@/...'),
name:'Home',
meta:{
keepAlive:true,
isBack:false
}
},
在index页面
<keep-alive>
<router-view v-if="$route.meta.keepAlive" ref="box"/>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" ref="box"/>
在有可能需要保持状态的a、b页面data里面加上scrollTop,并且处理数据和滚动条是否需要保持
因业务需求 创建页面会自动调用一次api 为防止重复调用 在activated() {}生命周期需要判断是否初次创建页面:isCreated
data() {
return {
isCreated:false,
scrollTop:0
}
},
created(){
//第一次创建
this.isCreated = true
},
beforeRouteEnter(to,from,next){
let name = ['...']
if(name.indexOf(from.name) !== -1) { //判断是从哪个路由过来的,页面不需要刷新获取新数据,直接用之前缓存的数据即可
to.meta.isBack = true
}
next()
},
methods:{
//getData(){
...
//防止后退激活时没有数据
this.isCreated = false
}
},
activated() {
//状态保持才进来此生命周期,不会进去created(){}、mounted(){}等生命周期
//但是页面刚创建的时候也会进这个生命周期、所以造成创建页面进来一次,后退又进来一次 所以如果获取数据是有重复的需要在此判断一下
if(!this.$route.meta.isBack) {
// 如果isBack是false,表明需要获取新数据,否则就不再请求,直接使用缓存的数据并且把滚动条回复到离开时的位置
//非第一次创建才进入 防止创建页面时再调用一次
if (!this.isCreated) {
//获取数据时需要初始化一下传给后端的参数 避免出问题
this.page = 1
this.goods = []
this.getData()
this.reload()
}
}else{
this.$refs.scrollView.scrollTop = this.scrollTop || 0
}
// 恢复成默认的false,避免isBack一直是true,导致下次无法获取数据
this.$route.meta.isBack = false
},
beforeRouteLeave(to,from,next){
//离开页面时把滚动条位置存起来
this.scrollTop = this.$refs.scrollView.scrollTop
next()
},