Sunday面试指南

Vue 的 KeepAlive 是什么?组件缓存后,生命周期会怎样变化?

🧑‍💻 面试官:Vue 的 KeepAlive 有什么作用?

🙋‍♂️ 我:缓存组件,切回来就不用重新创建了。

🧑‍💻 面试官:列表缓存了,轮询请求和窗口监听器也会自己停吗?

🙋‍♂️ 我:组件离开页面,应该就卸载了吧。

🧑‍💻 面试官:如果已经卸载,又怎么保留输入内容和滚动状态?

KeepAlive 保存的是组件实例;暂时离开界面,不等于实例已经销毁,也不等于后台工作自动停止。

面试速答(60 秒版)

KeepAlive 可以缓存被切换出去的组件实例,让它以后重新显示时保留状态,而不是每次都重新创建。

进入缓存组件的显示状态,会触发 activated;离开并进入缓存,会触发 deactivated。首次挂载也会触发 activated,deactivated 在最终卸载时也会触发。

可以用 include、exclude 控制按组件名称缓存哪些组件,用 max 限制实例数量;超过限制时,最近最少使用的缓存实例会被淘汰。

工程上要单独处理数据刷新、轮询、全局事件和缓存上限。保留旧页面不等于数据仍然有效,组件不显示也不保证副作用已经停下来。

组件停用进入缓存、重新激活返回页面、超限淘汰后卸载

知识点详解:组件离开页面后,究竟留下了什么

先看一个切换回来不该清空的页面

假设后台有一个搜索列表。用户输入条件、翻到第 4 页,再去看某一条详情。回来后,如果列表每次重新创建,输入和分页状态可能重新初始化。

KeepAlive 可以保留组件实例及其内部状态。切走时,它进入缓存;切回来时,同一个实例重新激活。

这里的缓存与接口数据缓存不是同一回事。组件内部保存的列表可能仍是几分钟前的数据。是否需要重新请求,要根据业务的新鲜度要求决定。

滚动状态还要看滚动容器、路由配置和你的恢复逻辑,不能只写上 KeepAlive 就保证所有滚动位置都正确。

激活和卸载,是两条不同的生命周期线

普通组件离开时通常走卸载流程;被缓存的组件离开时,先进入停用状态,之后仍可能回来。

下面是 Vue 3 的 TypeScript 组合式 API 示例。Python 不具备对应组件生命周期,不提供伪等价实现。

import { onActivated, onDeactivated } from 'vue';

let timer: ReturnType<typeof setInterval> | undefined;

function stopPolling() {
  if (timer !== undefined) clearInterval(timer);
  timer = undefined;
}

onActivated(() => {
  stopPolling();
  timer = setInterval(() => console.log('refresh'), 5000);
});

onDeactivated(stopPolling);

先停止已有定时器,是为了让启动动作可以重复执行。实际刷新接口还需要取消未完成请求或忽略过期结果。

注意,首次挂载也会激活。如果在 mounted 和 activated 各启动一次轮询,就可能在第一页已经跑了两份。

缓存数量和组件名称,也属于设计

include、exclude 依据组件名称匹配,不是依据路由 URL 随意猜测。Vue 3.2.34 起,script setup 组件可以根据文件名推断名称,但仍要核对你实际编译出的组件和匹配规则。

max 限制的是缓存实例数。达到上限后,会按最近最少使用的策略淘汰,淘汰的实例最终卸载。再次访问它就需要重新创建,不能承诺状态永远保留。

key 也会影响实例身份。每次给组件生成随机 key,可能让缓存不断出现新实例;不同参数是否应该复用同一个实例,要根据页面需求决定。

上线前,检查看不见的工作

我会先来回切换几次,观察请求、定时器和全局监听是否重复。再检查缓存淘汰后能否重新初始化,以及换用户或权限变化时是否保留了不该继续显示的旧状态。

如果页面需要实时数据,激活时可以重新拉取;如果可以接受一定时间内的旧数据,就按时间或版本判断是否刷新。

KeepAlive 省掉了部分重建工作,也留下了实例和数据。是否值得缓存,需要一起看切换体验、内存和数据有效期。

本题机制参考:Vue:KeepAlive。

面试官继续追问

activated 只在第二次回来时触发吗?

不是。第一次挂载时也会触发,被缓存后重新插入时也会触发。

deactivated 和 unmounted 是同一件事吗?

不是。deactivated 表示进入停用状态;淘汰或父级最终移除时还会卸载。deactivated 钩子在最终卸载时也会执行。

给所有页面都套 KeepAlive 好不好?

要看状态和内存。无需保留、数据敏感或实例很重的页面不一定适合;缓存需要范围和淘汰策略。

面试速记卡

  • KeepAlive:缓存组件实例,不是自动缓存接口新鲜度。
  • activated:首次挂载与重新激活都会触发。
  • deactivated:进入缓存时触发,最终卸载时也触发。
  • max:限制实例数,按最近最少使用淘汰。
  • 工程检查:轮询、全局监听、身份变化和内存。

公司面试真题

这道题暂未收录可核验的公司真题来源。你可以先阅读本文解析,或浏览已收录的公司面试真题。

浏览公司面试真题 →
简历汪永久免费在线制作简历,模板直接套用、导出无水印,永久免费、下载免费,不需要付费解锁任何功能。去写简历