Vue3 零基础每日笔记(011):生命周期钩子——在正确的时间做正确的事

一、前言

组件和人一样有完整的一生:出生(创建挂载)→ 成长(更新)→ 离世(卸载)。在每个关键节点,你都能"注册一个动作":挂载后发请求、卸载前清定时器。这些节点就是生命周期钩子。写代码最容易犯的错就是"时机不对"------页面还 没 DOM 就去操作它。今天把时机一次理顺。

二、一张人生时间轴看懂执行顺序

复制代码
<script setup> 执行        ← 相当于 Vue2 的 beforeCreate + created,最早的时机
    ↓
onBeforeMount()            ← 模板编译完成,还没渲染出真实 DOM
    ↓
onMounted()                ← ✅ DOM 已就绪!发请求、拿 ref、初始化图表都在这
    ↓ (数据变化,可循环多次)
onBeforeUpdate() → 真实 DOM 更新 → onUpdated()
    ↓ (调用卸载 / 切走页面)
onBeforeUnmount()          ← 组件还健在,收尾动作放这(清定时器、取消订阅)
    ↓
onUnmounted()              ← 彻底离世

只写常用的四个就够 90% 场景:setup、onMounted、onBeforeUnmount、onUnmounted。

三、基本用法

全部从 vue 导入,在 <script setup> 里直接调用注册:

vue 复制代码
<template>
  <p ref="box">{{ msg }}</p>
  <button @click="msg = '更新了'">更新</button>
</template>

<script setup>
import { ref, onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted } from 'vue'

const msg = ref('hello')
const box = ref(null)

console.log('1. setup 执行(最早,比所有钩子都早)')

onBeforeMount(() => console.log('2. onBeforeMount:还没 DOM'))
onMounted(() => {
  console.log('3. onMounted:DOM 就绪')
  console.log('拿到 DOM 元素:', box.value)  // ✅ 这里 ref 才有值
})
onBeforeUpdate(() => console.log('4. onBeforeUpdate:数据变了,DOM 还没变'))
onUpdated(() => console.log('5. onUpdated:DOM 也更新完了'))

onBeforeUnmount(() => console.log('6. onBeforeUnmount:临终遗嘱时间'))
onUnmounted(() => console.log('7. onUnmounted:彻底卸载'))
</script>

打开控制台点一点,每个节点的先后顺序一目了然,比背八遍文档都记得牢。

四、Vue2 → Vue3 对照表(老项目迁移必存)

Vue3 组合式 API 里钩子全部加 on 前缀,有两个直接改名:

Vue2(选项式) Vue3(组合式) 说明
beforeCreate 不需要了 <script setup> 本身就是
created 不需要了 同上,setup 执行时机等价
beforeMount onBeforeMount
mounted onMounted
beforeUpdate onBeforeUpdate
updated onUpdated
beforeDestroy onBeforeUnmount 改名了
destroyed onUnmounted 改名了

记住结论:created 里干的事(初始化数据、发请求),Vue3 直接写在 setup 顶层,不用包任何钩子。

五、综合实战:时钟组件(正确时机演示)

一个会走秒的时钟,挂载后启动,卸载前销毁------把最经典的"开/关定时器"时机写对:

vue 复制代码
<template>
  <p>当前时间:{{ now }}</p>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'

const now = ref('')
let timer = null

// 挂载后:启动定时器
onMounted(() => {
  timer = setInterval(() => {
    now.value = new Date().toLocaleTimeString()
  }, 1000)
})

// 卸载前:清掉定时器
onBeforeUnmount(() => {
  clearInterval(timer)
  timer = null
})
</script>

使用它的父组件加个开关按钮,切走再切回,控制台不会有任何定时器泄漏------onMounted 开的,onBeforeUnmount 必须关,成对出现是铁律。

【截图位置:时钟每秒走字的运行效果】

顺便看一个高频问题------父子组件的 mounted 顺序:父组件里引用子组件时,子组件的 onMounted 先执行,父组件的后执行(儿子先出生,爸爸才能算"生完了")。父组件要在 onMounted 里拿子组件内容时记住这条。

六、踩坑记录

  1. 在 setup 顶层直接操作 DOM / 用 ref :box.value 是 null------DOM 还没生成,必须放 onMounted 里
  2. 定时器/事件监听忘清理:组件切走了 setInterval 还在后台跑,页面越用越卡(内存泄漏)。开与关必须成对
  3. 把发请求包在 created 心态里套钩子:Vue3 直接写 setup 顶层即可,等价于 created,还少一层嵌套
  4. onMounted 是异步的不用 await:需要"请求完再渲染"用响应式数据 + v-if 控制骨架屏,而不是阻塞钩子
  5. async setup 会白屏 :<script setup> 顶层直接 await 需要配 Suspense(032 篇细讲),新手期别在 setup 顶层裸 await
  6. 在钩子里用箭头函数丢了 this:组合式 API 已经没有 this 了,全员箭头函数即可------这也是 Vue3 比 Vue2 心智负担小的地方

七、今日小结

  • 人生时间轴:setup(最早)→ onMounted(DOM 就绪)→ 更新钩子 → onBeforeUnmount → onUnmounted
  • 发请求、拿 ref、初始化第三方库 → onMounted
  • 清定时器、解绑事件 → onBeforeUnmount,与开启动作成对出现
  • Vue2 的 created 逻辑 = Vue3 的 setup 顶层;beforeDestroy/destroyed 改名为 onBeforeUnmount/onUnmounted

作者:陈志宝

下篇预告

还剩最后一块拼图:005、006 反复埋的"解构丢响应式"到底怎么破?下一篇 toRef 与 toRefs------响应式数据的"解构救星",也是通往组合式函数的最后一站。

相关推荐
Swilderrr11 小时前
论文精读:《Directory-Aware Query and Maintenance in Vector Databases》
笔记·学习
SatanII11 小时前
K8s 存储与配置管理|Volume、ConfigMap、Secret 核心笔记
笔记·rpc·kubernetes
_菜鸟果果11 小时前
高德地图 JS API 2.0 在国产 Linux/ARM 电脑上渲染失败 的排查与解决
linux·开发语言·javascript
Java后端的Ai之路11 小时前
前端技术Vue-09-webpack-vuejs-实战
前端·vue.js·webpack
迷途小羔羊12 小时前
项目概述
java·javascript·后端
迷迭绿12 小时前
Cesium 轨迹回放播放器
前端·javascript·cesium
I'mChloe13 小时前
飞牛NAS部署flatnotes实战:Docker、8080端口、Markdown笔记与固定地址访问
笔记·docker·容器
库玛西13 小时前
外部排序全解析:败者树、置换-选择排序与最佳归并树
c语言·数据结构·c++·笔记·考研·算法
摇滚侠13 小时前
《Java并发编程之美》第 2 章 并发编程的其他基础知识 阅读笔记 3
android·java·笔记