keep-alive 实现页面缓存

一、使用场景

vue实际开发中(开发的都是单页应用),我们都使用Vue-Router做页面导航,而每次切换路由的时候,页面都是会进行重新加载的,对应的所有周期页面被重新执行一遍。
但是,有一些场景却需要我们把页面状态保存下来,否则用户体验很不好,如:

  • 分页列表中,假设我们已经切换到第五页,这时我们进入了其中一条数据的详情页面,然后返回,这时如果不做特殊处理,会重新执行createdmounted生命周期,从而重新加载页面,默认就显示到第一页去了,绝望!!
  • 一个列表页中,存在条件筛选,查询到相关数据后,跳转到详情页面,然后再返回,列表默认会清空查询条件,显示所有数据。
二、keep-alive是什么
  • keep-aliveVue提供的一个内置组件,被keep-alive组件包裹的内部组件,其状态将被缓存
  • keep-alive包裹的组件,其生命周期只能被执行一次,再次进入时不会被执行
  • keep-alive包裹的组件,会自动新增两个生命周期函数activateddeactivated,每次进入都会被执行
  • keep-alive两个属性includeexclude,可以让keep-alive实现有条件的进行缓存。include匹配到的组件会被进行缓存,exclude匹配到的组件不会被缓存
三、keep-alive 实现路由页面缓存

keep-alive实现路由缓存主要有三种方式:

1. 缓存所有
<keep-alive>
  <router-view></router-view>
</keep-alive>

缺点:这样将缓存整个项目的所有路由
 

2. 使用include或者exclude

includeexclude 可以使用逗号分隔的字符串、正则、数组;并且匹配的都是组件的name属性

<!-- 逗号分隔字符串 -->
<keep-alive include="a,b">
  <router-view></router-view>
</keep-alive>

<!-- 正则表达式-->
<keep-alive :include="/a|b/">
  <router-view></router-view>
</keep-alive>

<!-- 数组 -->
<keep-alive :include="['a', 'b']">
  <router-view></router-view>
</keep-alive>

缺点:这样缓存页面,虽然可以实现部分组件的缓存,但是会出现生命周期只执行一次,第二次不管从什么地方进入,都不能重新加载页面
  

3. 根据v-if控制显示的router-view(条件缓存)

优点:可以实现从指定页面进入时缓存进入的页面,而从其余地方进入,进入的页面将被重新加载

如:一个List页面,只有从对应的Detial返回(跳转到列表)时,页面被缓存,而当从其余地方跳转到这个List组件时,页面都会被重新加载

实现步骤:

3.1 在需要路由缓存的页面路由meta属性中新增keepAlive,默认为true

{
  path: '/list',
  name: 'List',
  component: () => import('@/views/list/index.vue'),
  meta: {
    keepAlive: true
  }
}

3.2 设置keep-alive包裹router-view

// home.vue 或者 page.vue
<template>
  ...
  <keep-alive>
    <router-view v-if="$route.meta.keepAlive"></router-view>
  </keep-alive>
  <router-view v-if="!$route.meta.keepAlive"></router-view>
</template>

3.3 在路由守卫钩子中,控制页面是否缓存

  • List 页面
export default {
  // 从List页面离开时,修改keepAlive值为false,保证进入该页面时页面刷新
  beforeRouteLeave(to, from, next) {
    from.meta.keepAlive = false
    next()
  }
}
  • Detail 页面
export default {
  // 从Detail返回List时,修改List的keepAlive为true, 确保返回List页面时使用缓存不刷新页面
  // 因为离开List时,keepAlive被设置为了false;所以这时候不管从哪里进入到List页面,都是没有keep-alive缓存的;而在Detail离开的时候,又将List对应的keepAlive设置为了true,所以从Detail进入到List 就实现了页面缓存
  beforeRouteLeave(to, from, next){
    if(to.name === 'List') {
      to.meta.keepAlive = true
    }
    next()
  }
}

 
  
文章仅为本人学习过程的一个记录,仅供参考,如有问题,欢迎指出!

  • 9
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值