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 / 用 refbox.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------响应式数据的"解构救星",也是通往组合式函数的最后一站。

相关推荐
prog_61031 小时前
【笔记】用cursor手搓cursor(十)
人工智能·笔记·大语言模型·agent
YWL2 小时前
OpenLayers地图分享:URL参数同步+分享链接生成,让用户一键分享地图视角
前端·javascript·vue·openlayers
卤蛋fg62 小时前
vue 甘特图组件 vxe-gantt 依赖连接线可视化拖拽创建与双击删除
vue.js
梦醒沉醉2 小时前
5、表达式与运算符
javascript
浔溺3 小时前
al+大数据每日学习笔记36
大数据·笔记·学习
Q一件事3 小时前
ArcGIS中TypeError: can‘t multiply sequence by non-int of type ‘str‘错误
前端·javascript·arcgis
浔溺4 小时前
al+大数据每日学习笔记35
大数据·笔记·学习
WeiXin_DZbishe4 小时前
基于springboot大学生提问箱系统-计算机毕设【课程设计】72593
javascript·vue.js·spring boot·vscode·python·node.js·php
kyrie_sakura4 小时前
MySQL学习笔记4 -- select的7大子句,子查询
笔记·学习·mysql