Vue.js 中真正能安全操作 DOM 的时机是 mounted 钩子阶段,此时虚拟 DOM 已渲染为真实 DOM 并插入页面,this.$el 和 this.$refs 均可用,适合初始化第三方库、绑定事件等;updated 仅用于响应数据变更后的 DOM 后处理;created、beforeMount、beforeDestroy 等阶段不可靠或不推荐直接操作 DOM。

Vue.js 中真正能安全操作 DOM 的时机,是 mounted 钩子阶段。在此之前(如 created、beforeMount),DOM 尚未生成或未挂载,操作会失败或无效;在此之后(如 updated、beforeDestroy),虽可访问 DOM,但需注意更新逻辑和清理责任。
mounted:最常用且最稳妥的 DOM 操作入口
组件完成挂载后,虚拟 DOM 已渲染为真实 DOM 并插入页面,this.$el 和 this.$refs 均已可用。
- 适合初始化第三方库(如 Chart.js、Mapbox)、绑定原生事件、读取元素尺寸或位置
- 推荐用
ref显式标记目标元素,比this.$el.querySelector更精准、更语义化 - 若涉及子组件 DOM,需确认子组件也已完成 mounted(父子组件 mounted 顺序为:子 → 父)
updated:仅用于响应数据变更后的 DOM 后处理
每次响应式数据变化引发视图重渲染后触发,此时 DOM 已同步更新完毕。
将静态 Vue 页面(index.vue)改造为动态页面(Custom.vue);稿源仅限 index.vue、其引用的 CSS 与资源路径,禁止参考仓库内其他文件。Invoke when user wants to transform a static Vue page into a dynamic data-driven page with Element UI components.
- 适合在内容变动后调整样式、滚动定位、焦点管理等“副作用”操作
- 避免在 updated 中修改响应式数据,否则可能触发无限更新循环
- 注意:updated 不保证子组件也已完成更新,如需依赖子组件 DOM,建议配合
$nextTick或监听子组件 emit
需要避开的“危险区”
以下阶段不可靠或不推荐直接操作 DOM:
立即学习“前端免费学习笔记(深入)”;
-
created:data 和 methods 可用,但
$el和$refs为undefined,DOM 根本不存在 - beforeMount:模板已编译为虚拟 DOM,但尚未挂载到真实 DOM,页面仍是原始 HTML
- beforeDestroy / destroyed:DOM 节点可能已被 Vue 卸载或清空,操作无意义;应专注资源清理(如移除事件监听器、清除定时器)
进阶提示:异步与 ref 的配合要点
使用 ref 获取 DOM 时,必须确保在 mounted 或之后访问;若在条件渲染(如 v-if)中,需判断 this.$refs.xxx 是否存在。
- 动态 ref 名称需用方括号语法:
this.$refs[refName] - 列表中多个 ref 可用
ref数组形式(Vue 2.6+ 支持ref="itemRefs",返回 NodeList) - 对异步加载内容(如接口返回后才渲染的 DOM),应在数据更新后用
this.$nextTick(() => {...})确保 DOM 已就绪

















