Vue2中keep alive的生命周期有啥特殊之处?
不少刚开始学Vue2的同学,碰到keep - alive组件时总会疑惑:它的生命周期和普通组件咋不一样?为啥有的钩子函数突然“变”了?今天咱就把keep - alive的生命周期门道拆开来讲,从基础概念到实际场景,帮你把这部分知识吃透。
keep - alive是干啥的?先搞懂基础作用
Vue里的keep - alive是个内置组件,核心功能是缓存组件实例,打个比方,你做了个带Tab切换的页面,Tab A是商品列表,Tab B是购物车,要是没keep - alive,每次切到Tab A都得重新请求数据、渲染列表;用上keep - alive后,Tab A的组件实例会被“存起来”,切回来时不用重新创建、销毁,直接复用,性能一下子就上去了。
普通组件和被keep - alive包裹的组件,生命周期有啥区别?
先回忆普通组件的生命周期:从创建(created
)→ 挂载(mounted
)→ 更新(updated
)→ 销毁(destroyed
),是一条“从生到死”的线性流程。
但被keep - alive包裹后,生命周期因“缓存复用”特性产生变化,核心是多了activated
和deactivated
两个钩子,普通钩子执行逻辑也不同:
-
首次进入被缓存组件:
执行顺序为beforeCreate → created → beforeMount → mounted → activated
,这里mounted
仅在首次挂载时执行,后续复用不再触发。 -
切换离开该组件(触发“停用”):
此时触发deactivated
,组件实例被缓存,并未真正销毁。 -
再次切换回来(触发“激活”):
仅执行activated
,因组件未被销毁,mounted
这类挂载钩子不会再执行。 -
组件被彻底销毁时(如路由改变、keep - alive的
include/exclude
规则将其排除):
执行顺序是deactivated → beforeDestroy → destroyed
。
举个直观例子:做“首页 - 详情页”路由切换,首页用keep - alive缓存,首次进首页,mounted
执行(渲染DOM、请求初始数据);跳转到详情页,首页触发deactivated
(可在此暂停定时器);从详情页切回首页,首页触发activated
(可在此刷新最新数据),整个过程中,首页组件未被销毁,下次切回仍复用同一实例。
activated和deactivated这两个钩子咋用?
这两个钩子是keep - alive的“灵魂”,实际开发中用于处理组件激活/停用时的逻辑,看几个常见场景:
-
activated:组件“唤醒”时做事
比如列表页切回后,需拉取最新数据(需结合业务判断是否每次拉取);或者恢复页面滚动位置(如记录scrollTop,在activated里赋值),再如做实时消息页面,在activated
里启动定时器轮询新消息,切走暂停、切回再启动,既省资源又保及时性。 -
deactivated:组件“休眠”时做事
最典型的是清除定时器——若在activated
里开启定时器,必须在deactivated
里清除,否则切走后定时器持续运行会引发内存泄漏,还能临时保存状态,如表单填了一半,切走时把输入内容存到临时变量,切回再赋值。
keep - alive生命周期的执行顺序咋记?
不用死记,结合“缓存复用”逻辑理解更轻松:
- 首次渲染:和普通组件一样走“创建→挂载”流程,最后加
activated
(表示“激活完成,可使用”)。 - 切换离开:触发
deactivated
(表示“暂时不用,先缓存”)。 - 再次激活:仅触发
activated
(直接复用缓存,无需重新挂载)。 - 彻底销毁:先
deactivated
(标记缓存实例“要销毁”),再走普通组件销毁流程(beforeDestroy → destroyed
)。
可以类比“酒店住客”:首次入住(创建 + 挂载 + 激活)→ 临时外出(停用,房间保留)→ 回来续住(激活,无需重新办入住)→ 退房(销毁,房间清空),这样是不是好记多了?
实际开发中怎么用keep - alive生命周期优化?
结合场景看,这俩钩子实用性拉满:
-
场景1:表单页面缓存
用户填表单填到一半,切到其他页面再返回,内容还在,此时deactivated
不用销毁组件,保留数据;activated
里可做轻量验证(如检查必填项是否为空)。 -
场景2:后台多标签页系统
像很多管理系统,打开多个标签页(每个标签对应一个组件),用keep - alive缓存后,切换标签时,activated
里更新页面标题、面包屑;deactivated
里保存临时数据(如表格筛选条件、分页信息),切回直接复用,不用用户重新设置。 -
场景3:性能敏感页面
比如首页有复杂图表、动画,首次mounted
里初始化图表(创建Canvas、绑定事件);之后切走再返回,activated
里仅更新数据(如新统计数值),无需重新初始化图表,性能大幅提升。
注意点:若想强制刷新缓存组件(如用户登出后清空所有缓存),有两种方法:
- 给keep - alive加动态
key
,如:key="$route.fullPath"
,路由变化时强制销毁重建; - 手动调用
this.$destroy()
,主动销毁组件实例。
常见误区:activated能代替mounted吗?
不少同学觉得“mounted只执行一次,activated执行多次,把逻辑全放activated里就行”——这可不对!
mounted
是组件挂载完成(DOM渲染完毕)的钩子,适合做“一次性”初始化:如给DOM元素绑定事件、初始化第三方插件(富文本编辑器、图表库)。
activated
是组件激活的钩子,适合做“重复性”操作:如每次切回都请求数据、更新页面状态。
举个富文本编辑器组件的例子:
mounted
负责“初始化编辑器”:创建编辑器实例、配置工具栏、绑定输入事件;activated
负责“加载内容”:把用户上次保存的内容渲染到编辑器;deactivated
负责“临时保存”:把当前编辑内容存到临时变量,切回再用。
这样分工明确,既保证编辑器只初始化一次(性能好),又能在每次激活时更新内容(体验好)。
看完这些,再遇到keep - alive生命周期问题,是不是清晰多了?核心是记住activated
和deactivated
这两个“缓存专属”钩子,理解它们与普通生命周期的配合逻辑,再结合实际场景运用,性能优化和用户体验都能兼顾~
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。