Vue生命周期与keep-alive实战理解

Vue 生命周期与 keep-alive:我用真实项目终于搞清楚了

"生命周期"这个词在 Vue 教程里会很早出现,但很多人学了之后还是一知半解。 因为光看文档,没有感觉。这篇文章想用真实项目代码,帮你把它们"落地"。


先说一个语言上的误导

"生命周期" 这个词,听起来像是整个项目从打开到关闭的一段大流程。

但实际上,它属于每一个组件。

正确的理解是:

每个 Vue 组件实例,都有自己的出生、挂载、更新、离开、缓存激活的过程。 这些阶段,Vue 会自动调用对应的钩子函数,给你一个"插队"的机会。


🗓️ 最常用的几个生命周期钩子

created ------ 数据准备好了,但页面还没画出来

diff 复制代码
✅ 适合做什么:
- 发起不依赖 DOM 的数据请求
- 初始化变量
- 读取 Vuex / props

mounted ------ 页面已经渲染出来了,DOM 摸得到了

diff 复制代码
✅ 适合做什么:
- 操作 $refs(真实 DOM)
- 绑定滚动、键盘、resize 事件
- 初始化第三方 JS 库(图表、播放器、WebSocket 等)

beforeDestroy / destroyed ------ 组件要销毁了

diff 复制代码
✅ 适合做什么:
- 清除定时器
- 解绑事件监听
- 关闭 WebSocket
- 释放资源

activated ------ keep-alive 缓存的页面"重新回来了"

diff 复制代码
✅ 适合做什么:
- 每次回到这个页面时,重新拉数据
- 恢复某些需要刷新的状态

deactivated ------ keep-alive 缓存的页面"离开了,但没销毁"

diff 复制代码
✅ 适合做什么:
- 暂停正在播放的音频
- 停止轮询
- 暂停实时监听

🔁 keep-alive 会改变什么

keep-alive 是 Vue 的内置组件,作用是缓存被包住的组件实例

没有 keep-alive 的情况下,离开一个页面 = 销毁这个组件。

有了 keep-alive,离开页面之后组件不一定被销毁,而是被"冷冻"起来:

复制代码
首次进入缓存页:
  created → mounted → activated

离开缓存页(不销毁):
  deactivated

再次进入缓存页:
  activated  ← 直接从这里开始,跳过了 created 和 mounted!

这就是为什么你会在缓存相关的组件里,经常看到 activated 而不是 created


🔧 用真实项目代码来拆解

根实例的 created:应用一启动就执行一次

js 复制代码
// src/main.js
new Vue({
  router,
  store,
  render: h => h(App),
  created() {
    // 这里的 created 只在"整个应用开机"时执行一次
    store.commit('businessCoulmn/setWorkDetail', '');        // 重置业务状态
    store.commit('instantMessaging/setScreenfullBut', false); // 重置 IM 全屏状态
    store.commit('siteBar/addMenu', router);                  // 注入动态菜单
  },
}).$mount('#app');

这里的 created 是根实例的生命周期,属于"整个应用开机初始化",不属于任何页面。


登录页的 created + mounted:先清状态,再做页面效果

markdown 复制代码
created:
  - 清空本地存储
  - 重置菜单和 tab
  - 清空 token

mounted:
  - 启动背景动画效果

典型用法:

  • created 适合"先把旧状态清干净"
  • mounted 适合"页面展示出来之后做的事情"

IM 页面入口:created 做初始化

markdown 复制代码
created:
  1. 拿老师的聊天账号
  2. 拿 IM 配置
  3. 初始化 TIM SDK
  4. 绑定 TIM 事件
  5. 登录 IM

为什么用 created 而不是 mounted

因为这些步骤不需要操作 DOM ,提前在 created 里做,能更快完成初始化。


IM 布局组件:mounted 初始化 WebSocket

markdown 复制代码
mounted:
  - 初始化 WebSocket 连接

beforeDestroy:
  - 关闭 WebSocket
  - 停掉轮询

mounted 之所以适合初始化 WebSocket,是因为:

  • WebSocket 有时候需要操作 DOM
  • mounted 保证页面已经渲染,更安全

beforeDestroy 负责配套的清理工作,避免资源泄漏。


ConversationList 用 activated 而不是 created,是因为......

js 复制代码
// src/components/.../ConversationList/index.vue
activated() {
  this.handleGetWechatStudentList(); // 每次"回到页面"时刷新数据
}

为什么不用 created

因为这个组件被 keep-alive 包着。

  • 第一次进来会走 created
  • 切走再切回来,created 不会重新触发
  • activated 每次回来都会触发

所以这里的逻辑是:

arduino 复制代码
created  → 第一次初始化
activated → 每次"回来"时刷新数据

这是 keep-alive 场景下非常经典的写法。


MessageWindow 用 deactivated,是因为......

js 复制代码
// src/components/.../MessageWindow/index.vue
deactivated() {
  this.handlePauseAudio(); // 离开页面时暂停音频
}

为什么不用 beforeDestroy

因为这个组件被缓存了,切走页面时不是真正销毁 ,不会触发 beforeDestroy

会触发的是 deactivated,专门处理"缓存页离开时的收尾动作"。


🔄 用一次完整流程来理解

markdown 复制代码
1. 用户打开项目
   └─ main.js 创建根实例
   └─ 根实例 created 执行(初始化菜单、重置 IM 状态)

2. 用户登录
   └─ login.vue created 清空旧数据
   └─ login.vue mounted 显示背景动画

3. 进入 IM 聊天页
   └─ instant-messaging/index.vue created 做 IM 初始化
   └─ Layout/index.vue mounted 初始化 WebSocket

4. 用户切走页面
   └─ 缓存页面 → 触发 deactivated(不销毁)
   └─ 非缓存页面 → 触发 beforeDestroy(销毁)

5. 用户切回 IM 页面
   └─ 触发 activated
   └─ ConversationList 重新拉数据

⚠️ 不要混淆的三个东西

概念 是什么
生命周期 组件的出生、挂载、更新、离开、重现的各个阶段
watch 监听某个数据变化,不是生命周期
keep-alive 缓存机制,它会改变组件的生命周期表现

keep-alive 的存在,让 deactivated / activated 有意义。

没有 keep-alive 包着的组件,这两个钩子永远不会触发。


🏁 一句话总结

arduino 复制代码
Vue 生命周期不是"整个项目统一跑一遍的流程"
而是"每个组件实例自己的阶段变化"

keep-alive 改变的是"离开"和"回来"的行为:
  - 离开时不销毁 → deactivated
  - 回来时不重建 → activated

所以:
  created / mounted    → 用于首次初始化
  activated            → 用于每次回来时刷新
  deactivated          → 用于离开时收尾
  beforeDestroy        → 用于真正销毁时清理

这是 Vue2 学习系列第四篇。

下一篇:Vue、SPA、MPA 傻傻分不清?一篇弄清楚三者的关系。

相关推荐
慧一居士2 小时前
TanStack功能介绍和使用场景,对应 vue,react 完整使用示例
前端·vue.js
码路人2 小时前
VUE-组件命名与注册机制
vue.js
码路人2 小时前
src-components调用链与即时聊天组件树
vue.js
码路人2 小时前
Home双router-view与布局切换逻辑
vue.js
lizi662 小时前
uniapp uview-plus 自定义动态验证
前端·vue.js·微信小程序
踩着两条虫2 小时前
VTJ.PRO 在线应用开发平台概览
前端·vue.js·人工智能
英俊潇洒美少年2 小时前
Vue reactive 底层 Proxy 完整流程(依赖收集 + 触发更新)
前端·javascript·vue.js
周万宁.FoBJ2 小时前
vue源码讲解之 effect解析 (仅包含在effect中使用reacitve情况)
前端·javascript·vue.js
周淳APP3 小时前
【VDOM,Diff算法,生命周期,并发请求】
前端·javascript·vue.js