业务场景:
在a页面滑动列表,点击进入b页面,再返回a页面时,a页面保留滑动的位置和页面缓存。
解决思路:
使用路由的keepAlive方法,keepAlive为true就会保留页面缓存。(返回该页面不会执行created和mounted)。
- app.vue使用缓存机制。
- a页面跳转到b页面时,设置a页面的keepAlive为true、保存页面滚动高度。
- 路由守卫判断去的页面不是b页面就将keepAlive改为false,防止别的页面跳转到a页面还有缓存。
- 在activated恢复页面滚动高度。
解决方法:
vue_16">1.app.vue。使用缓存机制。
<template>
<div id="app">
<keep-alive>
<router-view v-if="$route.meta.keepAlive"/>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive">
<!--因为用的是v-if 所以下面还要创建一个未缓存的路由视图出口-->
</router-view>
</div>
</template>
注意keepAlive对应路由里面keepAlive大小写
jsbkeepAlivefalse_32">2.router.js。路由离开事件里判断要去的不是b页面就设置当前页面keepAlive为false。
防止别的页面跳转到a页面还有缓存,不会执行created和mounted。to.name严格区分大小写。
Vue.mixin({
beforeRouteLeave: function (to, from, next) {
// 去的不是b页,不需要缓存
if (to.name != 'b') {
this.$route.meta.keepAlive = false
}
}
})
如果还有更多,就这样判断
Vue.mixin({
beforeRouteLeave: function (to, from, next) {
// 去的不是bcd……页,不需要缓存
if (to.name != 'b' && to.name != 'c' && to.name != 'd') {
this.$route.meta.keepAlive = false
}
}
})
3.a页面 data中定义一个scroll变量
scroll: 0, //定义初始滚动高度
设置ref=“wrapper”,ref设置在滚动的div上。
<div ref="wrapper"></div>
a页面跳转到b页面时,设置a页面的keepAlive为true、保存页面滚动高度
method(){
//点击跳转到b页面
clickItem(item) {
let wrapperScrollTop = this.$refs.wrapper.scrollTop;//获取滚动高度
this.scroll = wrapperScrollTop; //保存滚动高度到scroll变量
this.$route.meta.keepAlive = true //点击跳转b页面之前,将a页面的keepAlive设置为true
this.$router.push({
name: "b",
}) //跳转到b页面
},
},
4.a页面在activated方法里,将页面滚动到之前的位置。
//挂载后和更新前被调用的。但如果该组件中没有使用缓存,也就是没有被<keep-alive>包裹的话,activated是不起作用的
activated() {
this.$nextTick(() => {
this.$refs.wrapper.scrollTop = this.scroll; //恢复滚动高度
//其他操作
})
},
获取滚动距离的方法有很多,这样的比较好操作。
题外话
如果想要c页面返回a页面时,a页面不要缓存。可以在路由守卫这样写
//从c去a,a不保留缓存
if(from.name == "c" && to.name == "a"){
to.meta.keepAlive = false
}