Vue 中 keep-alive 组件的生命周期钩子

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. 注意事项和最佳实践

注意事项:

  1. name 属性必需 :组件必须有 name 选项才能被 include/exclude 匹配
  2. 嵌套 keep-alive:Vue 2.2.0+ 支持嵌套使用,但应避免过度使用
  3. 动态组件 :与 <component :is="..."> 结合时最有用
  4. 内存管理 :注意内存泄漏,及时在 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 为缓存组件提供了精确的控制能力。合理使用这些钩子可以有效管理组件状态、优化性能,同时避免内存泄漏等问题。在实际开发中,结合路由配置和动态组件,可以创建出体验更流畅的单页应用。

相关推荐
前端一课1 小时前
别把人生过成一场等待退休的倒计时
前端
.Hypocritical.2 小时前
SpringBoot+Vue 前后端分离项目部署到云服务器
服务器·vue.js·spring boot
CENTER SAYS2 小时前
企业400电话办理全流程详解与材料准备(实操向)
前端·crm
:mnong2 小时前
Web 三维可视化技术对比:ParaView Web vs 本项目 wasm + Three.js
前端·webgl·opengl·opencl·科学可视化
Shirley~~2 小时前
three.js的调试面板工具
前端·3d
怕浪猫2 小时前
12个UI组件库,Star最低的下载最多
前端·javascript·面试
溪语流沙2 小时前
【Web全栈进阶】Vue3起步:组件、模板语法、响应式数据
前端·javascript·vue.js·css3
众链网络2 小时前
Agent 重试的工程解法:幂等、断点续跑与熔断怎么落地
java·前端·数据库·人工智能
User_芊芊君子2 小时前
JiuwenSwarm 协同智能体落地金融投研全流程:SwarmFlow 工作流编排与人机交互面板实测(A2UI v0.8 Web 通道适配)
前端·金融·人机交互
程序员大阳3 小时前
副队长CSS教程(37)–transition 过渡
前端·css·transition·过渡