Vue使用keep-alive实现详情页进入列表页缓存,其他页面进入列表页不缓存
场景:为了优化用户体验,当从商品详情页返回到商品列表页时,不需要再次请求商品列表数据。由此,我想到了使用
Vue
中的keep-alive
,但常规keep-alive
的使用方法仅满足任何条件下都缓存单个页面。但在实际过程中,我们从其他页面(如商品分类页)进入商品列表页时,应当是请求商品列表的数据,不再缓存该页面。这里,如果使用
keep-alive
的常规方法则无法满足需求,所以有了以下的解决方案。
1. 配置路由出口渲染组件
在App.vue
文件进行以下配置
1 2 3 4 |
<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
标识,进行判断是否从详情页返回该页面。
1 2 3 4 5 6 7 8 9 |
{ 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
。
1 2 3 4 5 6 7 8 |
beforeRouteEnter(to, from, next) { if (from.path == "/goodsDetail") { to.meta.isBack = true; } else { to.meta.isBack = false; } next(); }, |
3.2 不缓存页面,重新请求数据
其他页面进入缓存页面时,应重新请求数据,所以需要在页面加载之前(即activated
),将之前获取到的数据以及查询条件清空。
1 2 3 4 5 6 7 8 9 10 11 |
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
中定义滚动条的高度。具体做法如下:(返回记住滚动条的位置)
1 2 3 4 5 6 7 |
// 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