4.1 onMounted 软装进场

5 阅读4分钟

核心隐喻: onMounted 就像房子盖好后的软装进场(挂窗帘)。


一、概念速览

【30秒能读完】

定义:在组件的 DOM 元素 真正挂载到屏幕上之后,立即执行的回调函数。

import { onMounted } from 'vue'

onMounted(() => {
  console.log('房子盖好了,可以挂窗帘了')
})

特性

  1. DOM 已存在:此时能获取到 document.getElementById
  2. 异步执行:在浏览器渲染完第一帧后运行。
  3. 只跑一次:组件初始化时运行,更新时不运行。

二、逐题详解

小题1:onMounted 是什么意思?

目标:理解单词含义。

// Mount = 挂载
// 指组件从"图纸"变成"屏幕上的像素"

傻瓜口令:"Mount 就是挂,上墙才能画。"

小题2:怎么读?

目标:正确发音。

读音:/ɒn ˈmaʊntɪd/ (昂-茂-替-得)

小题3:必须写吗?

目标:明确必要性。

结论:不必须。 何时写:除此之外,都不用写。

  1. 需要操作 DOM(画图表、聚焦输入框)。
  2. 需要初始化第三方库。

小题4:script setup 不就是运行吗?为何还要它?

目标:区分 setup 和 onMounted。

<script setup>
  console.log('1. 画图纸 (Setup)')
  
  import { onMounted } from 'vue'
  onMounted(() => {
    console.log('3. 交房 (Mounted)')
  })
</script>

<template>
  <div>2. 盖房子 (Rendering...)</div>
</template>

傻瓜口令:"Setup 画图纸,Mounted 搞装修。"

小题5:显示前还是显示后?

目标:明确时序。

结论显示后。浏览器先把 HTML 画在屏幕上,用户眼睛看到了,然后 Vue 才执行 onMounted

小题6:能写 document.getElementById 吗?

目标:DOM 操作安全性。

<script setup>
import { onMounted } from 'vue'

// ❌ 错误:这时墙还没砌好
const el1 = document.getElementById('box') // null

onMounted(() => {
  // ✅ 正确:墙砌好了
  const el2 = document.getElementById('box') // 拿到元素
})
</script>

<template>
  <div id="box"></div>
</template>

傻瓜口令:"找元素,用 Mounted,别的地儿是空气。"

小题7:写三个会怎样?

目标:多重调用。

onMounted(() => console.log('我是第 1 个'))
onMounted(() => console.log('我是第 2 个'))
onMounted(() => console.log('我是第 3 个'))

// 结果:按顺序打印 1, 2, 3

傻瓜口令:"写几个跑几个,排队做核酸。"

小题8:能写 async 吗?

目标:异步支持。

onMounted(async () => {
  await fetchData()
  console.log('数据回来了')
})
// 现象:Vue 不会等你。它继续干别的事,你慢慢跑。

小题9:需要 import 吗?

目标:引入规则。

// ❌ 报错:onMounted is not defined
onMounted(() => {})

// ✅ 正确
import { onMounted } from 'vue'
onMounted(() => {})

傻瓜口令:"要用它,先引它。"

小题10:能套娃(写在里面)吗?

目标:嵌套规则。

// ❌ 禁止:异步套娃
setTimeout(() => {
  onMounted(() => {}) // 报错!Vue 找不到爹了。
}, 1000)

// ❌ 禁止:钩子套钩子
onMounted(() => {
  onMounted(() => {}) // 没意义,且危险。
})

傻瓜口令:"钩子别套娃,同步直接挂。"

小题11:v-if 切换会跑吗?

目标:条件渲染触发。

<template>
  <Child v-if="show" />
</template>

现象

  1. show = true -> Child 跑 onMounted
  2. show = false -> Child 销毁。
  3. show = true -> Child 再次onMounted

傻瓜口令:"v-if 就像开关,开了就挂载。"

小题12:反义词是什么?

目标:了解销毁。

单词onUnmounted (卸载) 场景:拆房子的时候(组件被销毁)。

小题13:SSR (服务器渲染) 会跑吗?

目标:服务端行为。

现象不跑比喻:服务器只打印图纸(HTML字符串),不盖实体房(DOM),所以没法装修。

小题14:能改 ref 吗?

目标:数据修改。

const count = ref(0)
onMounted(() => {
  count.value = 1 // 可以改
})
// 后果:浏览器可能重画一次。如果数据关联界面,用户可能看到闪烁。

小题15:写 alert 会怎样?

目标:阻塞行为。

现象alert 会卡住浏览器的主线程。 后果:虽然数据可能变了,但界面可能还没刷新。不要用 alert 调试生命周期。

小题16:vs window.onload

目标:区分网页加载与组件挂载。

onMountedwindow.onload
你家交房全小区交房
慢 (等图片、广告全加载)
只管这个组件管整个网页

小题17:vs Vue2 mounted

目标:版本对比。

结论:时机一样。 写法

  • Vue2: mounted() { ... } (选项)
  • Vue3: onMounted(() => { ... }) (组合)

小题18:父子组件顺序?

目标:挂载顺序。

graph TD
    父Setup --> 子Setup
    子Setup --> 子Mounted
    子Mounted --> 父Mounted

傻瓜口令:"子先挂,父后挂。" (孩子先站稳,爸爸才放心)

小题19:能放在 if 里吗?

目标:条件注册。

if (Math.random() > 0.5) {
  onMounted(() => console.log('运气好才跑')) // ✅ 可以
}

小题20:有参数吗?

目标:参数签名。

结论无参数onMounted((params?) => ...) 里的参数是 undefined

小题21:有返回值吗?

目标:返回值处理。

结论:Vue 忽略 你的返回值。写 return 也没用。

小题22:漏写括号会怎样?

目标:语法检查。

import { onMounted } from 'vue'

// ❌ 没调用函数
onMounted 

// 现象:啥也不会发生,控制台不报错,但钩子没注册。

小题23:必须写箭头函数吗?

目标:回调形式。

结论:必须传一个函数

  1. onMounted(() => {}) (推荐,箭头函数)
  2. onMounted(function() {}) (普通函数,也可以)
  3. onMounted(myFunction) (传函数名,也可以)

三、常见坑位

表现解法
Setup 里找 DOMdocument.getElementById 返回 null移到 onMounted 里写
异步套钩子setTimeout 里写 onMounted 报错无效提出来,放在最外层
忘删监听器组件销毁后,resize 事件还在跑onUnmountedremoveEventListener

四、速查表

特性说明
心智模型房子盖好 -> 软装进场
核心 APIimport { onMounted } from 'vue'
执行时机DOM 渲染完成之后
常见陷阱不要以为它是 window.onload (它比那个快)

五、脑图回顾

graph LR
    A[Script Setup] -->|1. 画图纸| B(Rendering)
    B -->|2. 盖房子| C[浏览器显示 DOM]
    C -->|3. 软装进场| D[onMounted 执行]
    D --> E{你要干嘛?}
    E -->|找元素| F[聚焦/画图]
    E -->|发请求| G[拿数据]