keep-alive的理解

核心概念

keep-alive是vue的一个内置组件,用于缓存不活动的组件实例。当切换组件时,它的状态会被保留在内存中,避免重复渲染,提升性能 下面是一个快速了解 keep-alive的表格:

特性维度 说明
​功能​ 缓存非活跃组件实例,避免重复销毁和创建,保持组件状态(如数据、滚动位置)
​核心属性​ include:指定缓存的组件名(字符串、正则、数组) exclude:指定不缓存的组件名 max:最大缓存实例数(采用LRU算法)
​生命周期钩子​ activated:组件被激活(从缓存中恢复)时触发 deactivated:组件被停用(进入缓存)时触发
​常见应用场景​ 表单页保留用户输入 列表页保持滚动位置和过滤条件 Tab页切换 路由组件缓存(需结合Vue Router)
​注意事项​ 组件需具名(name选项)以便 include/exclude匹配 注意及时清理非响应式资源(如定时器、事件监听)防止内存泄漏 合理使用 max控制缓存量

关键原理

keep-alive通过维护一个缓存对象 (vue2中使用普通对象,vue3使用Map)和一个键数组(vue2使用数组,vue3使用Set)来工作 被包裹的组件切换时,vue会检查名称是否匹配include和exclude,如果匹配缓存条件,组件实例会被存入缓存,否则销毁。当命中缓存时,实例直接从缓存中复用

max属性也很重要,大量缓存会造成内存的压力,设置max,确定最大缓存数量,缓存实例超过上限时,最久未被访问的实例会被销毁

实践应用

基本用法:

  1. 缓存动态组件 使用component组件配合is属性进行动态切换时,用keep-alive包裹实现缓存
vue 复制代码
	<template>
	  <keep-alive>
	    <component :is="currentComponent"></component>
	  </keep-alive>
	</template>
  1. 缓存路由组件 结合vue-router的router-view使用
vue 复制代码
	<template>
	  <keep-alive>
	    <router-view></router-view>
	  </keep-alive>
	</template>
  1. 条件缓存(include/exclude) 精确控制哪些组件需要缓存或不需要缓存。组件必须设置name
vue 复制代码
	<keep-alive :include="['Home', 'About']" :exclude=" /^Temp/" :max="5">
	  <component :is="currentView"></component>
	</keep-alive>
  1. 在vue router中按路由缓存 meta定义是否需要缓存
js 复制代码
	// router.js (Vue Router 4)
	const routes = [
	  {
	    path: '/list',
	    name: 'ListPage',
	    component: () => import('./ListPage.vue'),
	    meta: { keepAlive: true } // 需要缓存
	  },
	  {
	    path: '/detail/:id',
	    name: 'DetailPage',
	    component: () => import('./DetailPage.vue'),
	    meta: { keepAlive: false } // 不需要缓存
	  }
	];

在根组件(如 App.vue)中根据路由的 meta.keepAlive条件渲染:

vue 复制代码
	<template>
	  <router-view v-slot="{ Component }">
	    <keep-alive>
	      <component :is="Component" v-if="$route.meta.keepAlive" />
	    </keep-alive>
	    <component :is="Component" v-if="!$route.meta.keepAlive" />
	  </router-view>
	</template>

keep-alive生命周期变化

  • 首次进入组件 :beforeCreate-> created-> beforeMount-> mounted-> activated
  • 再次进入(激活)​ :activated
  • 离开(失活)​ :deactivated

​注意 ​:传统的 mounted等钩子在首次加载后再次切换回来时不会再次触发 。因此,如果需要数据刷新,应将逻辑放在 activated钩子中

vue3中是注册onActivated和 onDeactivated函数来

vue 复制代码
	<script setup>
		import { onActivated, onDeactivated } from 'vue';
		
		onActivated(() => {
		  // 组件被激活时执行,例如重新请求数据
		  console.log('Component activated');
		});
		
		onDeactivated(() => {
		  // 组件被缓存时执行,例如清除定时器或取消请求
		  console.log('Component deactivated');
	});
	</script>

常见问题

  1. 组件必须具名
  2. 合理控制缓存数量
  3. 及时清理资源
  4. 何时使用keep-alive
推荐使用 ✅ 不建议使用 ❌ 注意事项
表单页跳转后返回需保留数据 静态内容展示 结合路由 meta 标记
长列表滚动位置恢复 - 配置路由的滚动行为
高频切换的 Tab 页 - 设置 max 防内存溢出
需要保持组件状态以避免重复渲染和请求的复杂页面 组件内容总是实时更新,无需保持状态的页面 在 activated中处理需要更新的逻辑

图表

相关推荐
知了学历孙老师2 小时前
小自考的校考和统考,出题方和难度差在哪
java·大数据·前端
ShineWinsu4 小时前
对于JavaScript:操作元素的解析
开发语言·前端·javascript·面试·web·dom·元素
福兮说5 小时前
JSON 格式正确,数据就可靠吗?我用一份自编配置检查类型与空值
java·前端·json
程序员老赵7 小时前
Docker 部署青龙面板:轻松搭建定时任务管理平台
前端·docker·开源
Swot7 小时前
Asciidoctor 公式数字下标错位问题:原因分析与解决方案
前端
Swot7 小时前
leo-editor 中将 Markdown 内容转成 asciidoc 格式
前端
狒狒AI7 小时前
Remotion / GSAP+Three / HyperFrames / Skia 四栈实测:代码渲染知识视频的选栈方法(附开源技能)
前端·人工智能·aigc
修炼的dance7 小时前
浏览器里导出H.265,8.5秒和55.5秒差在硬件
前端
补码缩写7 小时前
WebCodecs选编码器,探测之后还要验解码和播放
前端
大文说跨境7 小时前
亚马逊多账号管理浏览器怎么选?云登/紫鸟/AdsPower 对比
java·前端·自动化