场景:为了优化用户体验,当从商品详情页返回到商品列表页时,不需要再次请求商品列表数据。由此,我想到了使用
Vue
中的keep-alive
,但常规keep-alive
的使用方法仅满足任何条件下都缓存单个页面。但在实际过程中,我们从其他页面(如商品分类页)进入商品列表页时,应当是请求商品列表的数据,不再缓存该页面。这里,如果使用
keep-alive
的常规方法则无法满足需求,所以有了以下的解决方案。
1. 配置路由出口渲染组件
在App.vue
文件进行以下配置
<keep-alive>
<router-view v-if="route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!route.meta.keepAlive"></router-view>
2. 在路由选项中,配置meta
属性和isBack
标识
在路由文件中,配置meta属性keepAlive
为true
时,表示缓存该页面;同时,配置isBack
标识,进行判断是否从详情页返回该页面。
{
path: '/goodsList',
name: 'GoodsList',
component: require('@/page/index/goods/GoodsList'),
meta: {
keepAlive: true,
isBack: false
}
},
3. 在缓存的Vue文件中做判断
在需要缓存的列表文件中(如GoodsList.vue
),进行以下配置
3.1 判断需要缓存的页面
通过beforeRouteEnter(to, from, next)
,来判断路由是从哪里来跳转的,如果是从详情页跳转的,则将当前路由对象的meta.isBack
设置为true
,否则设为false
。
beforeRouteEnter(to, from, next) {
if (from.path == "/goodsDetail") {
to.meta.isBack = true;
} else {
to.meta.isBack = false;
}
next();
},
3.2 不缓存页面,重新请求数据
其他页面进入缓存页面时,应重新请求数据,所以需要在页面加载之前(即activated
),将之前获取到的数据以及查询条件清空。
activated() {
let that = this;
// 第一次和非详情页进入页面时 isBack都为false,即需要重新请求数据
if (!this.route.meta.isBack) {
// 清空查询条件和数据 并重新请求数据
that.goods = [];
that.params.p = 1;
that.getGoodsList()
}
this.route.meta.isBack = false;
},
相关问题:
使用keep-alive
缓存时,会出现无法缓存滚动条高度的情况,这里需要在activated
中定义滚动条的高度。具体做法如下:(返回记住滚动条的位置)
// data中定义
homeTop : 0,
// activated中设置高度
document.getElementById('app').scrollTop = this.homeTop || 0
// 还有第三步,仍然有点问题,我未使用到第三步,就已经达到想要的效果了
文档:https://www.cnblogs.com/_error/p/10118257.html
参考资料
https://segmentfault.com/a/1190000017456786?utm_source=tag-newest