Vue 中 keep-alive 组件的生命周期钩子
本文来自于我关于 Vue生命周期钩子 的系列文章。欢迎阅读、点评与交流~
1、Vue 中的生命周期钩子
2、Vue 中 keep-alive 组件的生命周期钩子

1. keep-alive 组件概述
keep-alive 是 Vue 的内置组件,用于缓存不活动的组件实例,而不是销毁它们。这样可以:
- 保留组件状态,避免重新渲染
- 提高应用性能
- 减少重复的 DOM 操作
2. 基本用法
vue
<template>
<div>
<keep-alive>
<component :is="currentComponent"></component>
</keep-alive>
</div>
</template>
3. 专门的生命周期钩子
被 keep-alive 包裹的组件会获得两个额外的生命周期钩子:
activated
- 调用时机:组件被激活(从缓存中取出并插入到 DOM 中)时调用
- 使用场景:重新获取数据、开启定时器、重新绑定事件等
deactivated
- 调用时机:组件被停用(从 DOM 中移除并存入缓存)时调用
- 使用场景:清除定时器、取消事件监听、释放资源等
4. 完整生命周期执行顺序
首次加载
javascript
// 组件第一次进入时
created() → mounted() → activated()
切换到其他组件(当前组件被缓存)
javascript
// 当前组件被离开
deactivated()
再次切换回来
javascript
// 再次进入缓存的组件
activated()
组件被销毁(当离开路由或 keep-alive 被移除)
javascript
// 如果是直接离开路由
deactivated() → beforeDestroy() → destroyed()
// 注意:如果组件被 keep-alive 缓存,则不会触发 beforeDestroy 和 destroyed
5. 实际示例
vue
<template>
<div>
<button @click="toggle">切换组件</button>
<keep-alive>
<ComponentA v-if="showA" />
<ComponentB v-else />
</keep-alive>
</div>
</template>
<script>
// ComponentA.vue
export default {
name: 'ComponentA',
data() {
return {
timer: null,
count: 0
}
},
created() {
console.log('ComponentA created')
},
mounted() {
console.log('ComponentA mounted')
},
activated() {
console.log('ComponentA activated')
// 重新开启定时器
this.timer = setInterval(() => {
this.count++
console.log('定时器运行中:', this.count)
}, 1000)
},
deactivated() {
console.log('ComponentA deactivated')
// 清除定时器
if (this.timer) {
clearInterval(this.timer)
this.timer = null
}
},
beforeDestroy() {
console.log('ComponentA beforeDestroy')
},
destroyed() {
console.log('ComponentA destroyed')
}
}
</script>
6. keep-alive 的属性配置
vue
<!-- 只缓存特定组件 -->
<keep-alive include="ComponentA,ComponentB">
<component :is="currentComponent"></component>
</keep-alive>
<!-- 排除某些组件 -->
<keep-alive exclude="ComponentC">
<component :is="currentComponent"></component>
</keep-alive>
<!-- 使用正则表达式 -->
<keep-alive :include="/ComponentA|ComponentB/">
<component :is="currentComponent"></component>
</keep-alive>
<!-- 限制最大缓存实例数 -->
<keep-alive :max="5">
<component :is="currentComponent"></component>
</keep-alive>
7. 与 Vue Router 结合使用
javascript
// router.js
const routes = [
{
path: '/page1',
component: Page1,
meta: {
keepAlive: true // 需要缓存
}
},
{
path: '/page2',
component: Page2,
meta: {
keepAlive: false // 不需要缓存
}
}
]
vue
<!-- App.vue -->
<template>
<div id="app">
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
</div>
</template>
8. 注意事项和最佳实践
注意事项:
- name 属性必需 :组件必须有
name选项才能被include/exclude匹配 - 嵌套 keep-alive:Vue 2.2.0+ 支持嵌套使用,但应避免过度使用
- 动态组件 :与
<component :is="...">结合时最有用 - 内存管理 :注意内存泄漏,及时在
deactivated中清理资源
最佳实践:
javascript
export default {
name: 'MyComponent', // 必须设置 name
data() {
return {
// 数据会被缓存
}
},
activated() {
// 可以在这里重新获取可能需要更新的数据
if (this.needsRefresh) {
this.fetchData()
}
},
deactivated() {
// 清理工作
this.cancelPendingRequests()
clearInterval(this.timer)
},
methods: {
// 如果需要刷新数据的逻辑
fetchData() {
// 获取数据
},
cancelPendingRequests() {
// 取消未完成的请求
}
}
}
9. Vue 3 中的变化
在 Vue 3 中,keep-alive 的用法基本保持不变,但生命周期钩子名称有变化:
javascript
// Vue 3 Composition API
import { onActivated, onDeactivated } from 'vue'
export default {
setup() {
onActivated(() => {
console.log('组件被激活')
})
onDeactivated(() => {
console.log('组件被停用')
})
}
}
总结
keep-alive 组件的生命周期钩子 activated 和 deactivated 为缓存组件提供了精确的控制能力。合理使用这些钩子可以有效管理组件状态、优化性能,同时避免内存泄漏等问题。在实际开发中,结合路由配置和动态组件,可以创建出体验更流畅的单页应用。