mounted 钩子中无法获取 DOM 的根本原因是渲染异步与条件渲染延迟;应结合 nextTick 等待更新完成,并优先使用 ref 而非 querySelector,对 v-if 等场景需在子组件 mounted 或 watch 响应式数据后操作。

在 Vue 2 或 Vue 3 的 Options API 中,mounted 是首个能安全操作真实 DOM 的生命周期钩子。但很多初学者会发现:明明写了 document.getElementById 或 ref,却拿不到元素——不是 null,就是报错。核心原因只有一个:DOM 渲染尚未完成或节点未就绪。
确保模板已渲染完成再查 DOM
Vue 的响应式更新和 DOM 渲染是异步的。mounted 触发时,模板已挂载,但若组件内有 v-if、动态组件、异步数据导致的条件渲染,对应 DOM 可能还没生成。
- 检查是否用了
v-if控制目标元素显示,改为v-show(它只切样式,不销毁 DOM)可快速验证 - 如果依赖
props或data异步加载(比如从 API 拿到数据后才渲染某块内容),不能直接在mounted里查,要等数据到位再查 - 简单办法:加个
this.$nextTick()(Vue 2)或nextTick()(Vue 3),它会在下一次 DOM 更新循环结束之后执行回调
优先用 ref 而非 querySelector
手动用 document.querySelector 容易受全局干扰,且难以和 Vue 的响应式逻辑对齐;ref 是 Vue 推荐的、更可靠的方式。
- 在模板中给元素加
ref="myInput" - 在
mounted中通过this.$refs.myInput(Vue 2)或ref.value(Vue 3 Composition API)访问 - 注意:ref 在
mounted时不一定立即可用(尤其配合v-if),所以仍建议包裹在nextTick中
处理 v-if 和动态组件的延迟场景
当目标元素由 v-if 控制,或来自 ,它的挂载时机晚于父组件的 mounted。
- 把操作逻辑移到子组件自己的
mounted钩子里(最干净) - 父组件监听子组件的自定义事件(如
@ready),由子组件在自己 mounted 后触发 - 使用
watch监听相关响应式数据变化,一旦满足渲染条件,再执行 DOM 操作
Vue 3 Composition API 的写法差异
如果你用的是 setup() + onMounted,要注意 ref 的解构陷阱:
- 定义
const myRef = ref(null),模板中写- 在
onMounted(() => { nextTick(() => { console.log(myRef.value) }) })中取值- 不要解构
myRef.value到局部变量,否则失去响应性,也拿不到真实 DOMDOM 操作本身不难,难的是理解 Vue 的渲染节奏。抓住“渲染异步”和“条件渲染延迟”两个关键点,配合
nextTick和ref,90% 的获取不到问题都能解决。 - 在










