Vuemounted生命周期详解
## Vue 中 mounted 生命周期作用详解:组件挂载后的关键时刻 在 Vue 组件的生命周期中,`mounted` 钩子扮演着至关重要的角色。它在组件挂载到 DOM 后立即触发,标志着组件已完全呈现在用户界面上。本文将深入探讨 `mounted` 的作用,包括初始化依赖 DOM 的第三方库(如 ECharts、地图 SDK)、直接操作 DOM 元素(推荐使用 `ref`)、发送依赖 DOM 尺寸的请求以及设置全局事件监听器等常见应用场景。同时,我们将对比 `mounted` 与 `created` 的区别,阐述何时选择哪个钩子,以及在 `mounted` 中进行数据请求的最佳实践。最后,我们将重点介绍如何在 `mounted` 中安全地操作 DOM,避免常见的陷阱,提升 Vue 应用的性能和可维护性。理解 `mounted` 钩子,是掌握 Vue 组件生命周期的关键一步。
mounted钩子在Vue组件挂载到DOM后触发,用于执行依赖DOM的操作。1. 初始化需DOM的第三方库(如ECharts、地图SDK);2. 直接操作DOM元素(推荐使用ref而非querySelector);3. 发送依赖DOM尺寸的请求;4. 设置全局事件监听器(须在beforeUnmount中清理以防内存泄漏)。与created区别在于:created无DOM访问权限,适合早于DOM阶段的数据请求;mounted有DOM访问权(this.$el、this.$refs),适合需真实DOM的逻辑。数据请求优先放created以提升性能,仅当依赖DOM时才放mounted,SSR场景下mounted不执行,需注意同构兼容性。

mounted 是 Vue 组件生命周期中一个非常关键的钩子,它在组件挂载到DOM之后立即被调用。简单来说,就是当你的组件在浏览器里“活过来”并呈现在用户眼前时,这个钩子就触发了。它的主要作用是执行那些需要DOM存在的操作,比如初始化第三方库、发送数据请求(如果数据依赖DOM),或者直接操作DOM元素。

解决方案
在我看来,理解 mounted 钩子,就像理解一个舞台剧的开幕。created 阶段是演员在后台准备,剧本都捋顺了,数据也到位了。但真正的“表演”——也就是组件在用户屏幕上呈现——得等到 mounted。在这个时刻,你的组件模板已经被编译成真实的HTML元素,并且被插入到了文档流中。这意味着,你终于可以安全地访问到 this.$el(组件的根DOM元素)以及通过 ref 标记的任何子元素了。
为什么这很重要?因为很多前端操作,尤其是与第三方库交互,或者需要测量、绘制DOM的场景,都必须在DOM元素实际存在后才能进行。比如,你想用ECharts画个图,或者用D3.js操作SVG,这些库都需要一个真实的DOM容器来承载它们的输出。如果你在 created 里就尝试这些,那多半会报错,因为容器还没影儿呢。

我个人在使用 mounted 时,最常见的场景就是:
- 初始化需要DOM的第三方库:比如一个日历选择器、一个富文本编辑器、一个图表库(ECharts, Chart.js)、或者一个地图SDK(高德、百度地图)。这些东西都需要一个宿主DOM元素才能工作。
- 直接操作DOM:虽然Vue推崇数据驱动,尽量少直接操作DOM,但总有些时候你不得不这么做。比如,你想给某个特定的元素添加一个非Vue管理的事件监听器,或者做一些复杂的动画,甚至只是简单地获取一个元素的实际宽度或高度。
- 发送依赖DOM的请求:虽然大部分数据请求在
created阶段就可以发了,但如果你的数据请求参数需要依赖DOM的尺寸、位置等信息,那mounted就是合适的时机。比如,你可能需要根据容器的宽度来决定加载哪种尺寸的图片。 - 设置全局事件监听:例如,监听
window的resize事件来响应式调整布局,或者监听document的点击事件来关闭一个弹出层。不过,这里有个小提醒,在mounted里添加的全局事件监听器,记得在beforeUnmount里移除,不然可能会导致内存泄漏。
mounted 与 created 的区别:何时选择谁?
说实话,这是个老生常谈的问题,但确实是理解Vue生命周期的核心。简单来说:

created:这个钩子是在组件实例被创建之后、数据观测 (data observation) 和属性/方法初始化完成之后立即调用的。此时,组件的数据data、计算属性computed、方法methods等都已经可用了。但是,DOM还没有被渲染。换句话说,你还看不到this.$el,也没有任何真实的HTML元素。- 适用场景:我通常会把不依赖DOM的数据请求放在这里。比如,加载用户配置、初始化一些不涉及UI的业务逻辑。这样做的好处是,数据可以更早地开始加载,甚至在组件的DOM结构还没完全准备好之前,这样用户感知到的加载时间可能会更短。
mounted:正如前面所说,这个钩子是在组件的模板被渲染成真实的DOM节点,并且被挂载到页面上之后才调用的。此时,this.$el已经指向了组件的根DOM元素,你也可以通过this.$refs访问到模板中带有ref属性的子元素。- 适用场景:所有需要操作或依赖真实DOM的操作。比如,初始化第三方UI库、获取DOM元素的尺寸、设置Canvas绘图上下文等。
我个人在实际项目中,如果只是单纯地获取数据,通常会优先选择 created。因为数据加载往往是异步的,早点开始总没错。但如果我的组件需要一个图表,而这个图表必须绘制在一个特定的 div 里,并且可能需要根据这个 div 的实际宽度来初始化,那么 mounted 才是我的不二选择。
mounted 中进行数据请求:是最佳实践吗?
这个问题其实没有绝对的“是”或“否”,更多的是“看情况”。
从性能优化的角度看,如果你的数据请求不依赖于DOM,那么在 created 中发起请求通常是更好的选择。因为 created 阶段比 mounted 更早,这意味着你的数据可以在组件渲染DOM的同时开始加载,甚至可能在DOM渲染完成之前数据就已返回。这样可以避免用户在看到页面结构后,还要等待数据填充的空白期。尤其是在一些需要快速响应的场景下,这一点点的提前量可能就会带来更好的用户体验。
但是,总有那么些特殊情况,你可能不得不把数据请求放在 mounted 里:
- 数据请求依赖DOM尺寸或属性:比如,你需要根据组件渲染后的实际宽度来决定请求不同分辨率的图片,或者为图表组件获取数据时,需要先初始化图表容器才能知道其可用的绘制区域大小。这种情况下,
mounted是你唯一的选择,因为只有这时DOM才真正可用。 - 与第三方库结合:有些第三方库可能需要先在
mounted中完成初始化,然后才能通过其API发起数据请求。虽然这种情况相对少见,但确实存在。
还需要注意的是 SSR (Server-Side Rendering) 的场景。在SSR中,mounted 钩子是不会在服务器端执行的,因为它涉及到浏览器环境的DOM操作。而 created 钩子则会在服务器端执行。所以,如果你正在构建一个同构应用(Isomorphic App),并且希望数据在服务器端就能预取,那么 created 或 beforeCreate (或者 Composition API 中的 setup 函数顶层)是更合适的选择。在 mounted 中发起的请求只会在客户端执行。
所以,我的建议是:优先考虑在 created 中进行数据请求。如果你的数据请求确实需要DOM的存在,或者你的应用是纯客户端渲染,那么在 mounted 中进行也完全没问题。关键在于理解不同生命周期钩子的执行时机和它们能访问到的上下文。
如何在 mounted 中安全地操作 DOM?
在 mounted 钩子中操作DOM,是其最核心的功能之一。但要“安全”地操作,意味着要遵循一些最佳实践,避免常见的坑。
首先,Vue本身是数据驱动的,它鼓励我们通过修改数据来让视图自动更新,而不是直接操作DOM。但总有一些场景,你确实需要绕过Vue的响应式系统,直接与底层的DOM元素打交道。
1. 使用 this.$el 访问根元素:this.$el 指向当前组件的根DOM元素。如果你只需要操作组件的最外层容器,这个属性非常方便。
<template>
<div class="my-component">
<!-- content -->
</div>
</template>
<script>
export default {
mounted() {
// 假设你想给这个根div添加一个类名,或者获取它的宽度
console.log('Component root element:', this.$el);
this.$el.style.backgroundColor = 'lightblue';
}
}
</script>2. 使用 ref 访问特定子元素(推荐):
这是在Vue中访问组件内部特定DOM元素的首选方式。通过在模板元素上添加 ref 属性,你可以在 mounted 之后,通过 this.$refs 对象来访问到这些元素。
<template>
<div>
<canvas ref="myCanvas"></canvas>
<button @click="drawOnCanvas">Draw</button>
</div>
</template>
<script>
export default {
mounted() {
// 初始化一个Canvas上下文,通常需要等到DOM元素可用
const canvas = this.$refs.myCanvas;
if (canvas) { // 总是检查一下,以防万一
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, 100, 100);
}
},
methods: {
drawOnCanvas() {
// 可以在mounted之后,通过方法继续操作这个DOM元素
const canvas = this.$refs.myCanvas;
if (canvas) {
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'blue';
ctx.fillRect(50, 50, 100, 100);
}
}
}
}
</script>安全操作的注意事项:
- 避免直接使用
document.querySelector或getElementById:尽管它们能工作,但这种方式会使你的组件与全局DOM结构紧密耦合,降低组件的可复用性。如果页面上有多个相同组件的实例,或者DOM结构发生变化,你的选择器可能会失效或选中错误的元素。ref机制是Vue提供的一种更安全、更局部的访问方式。 - 清理副作用:如果你在
mounted中添加了全局的事件监听器(比如window.addEventListener或document.addEventListener),或者初始化了需要销毁的第三方实例(比如地图实例、图表实例),那么务必在组件销毁前(即beforeUnmount钩子中)进行清理。否则,这些监听器或实例会继续存在于内存中,导致内存泄漏。
<template>
<div>
<p>Window width: {{ windowWidth }}</p>
</div>
</template>
<script>
export default {
data() {
return {
windowWidth: window.innerWidth
};
},
mounted() {
// 在mounted中添加resize事件监听器
this.handleResize = () => {
this.windowWidth = window.innerWidth;
};
window.addEventListener('resize', this.handleResize);
},
beforeUnmount() {
// 在组件销毁前移除监听器,防止内存泄漏
window.removeEventListener('resize', this.handleResize);
}
}
</script>- 警惕非响应式更新:当你直接操作DOM时,Vue的响应式系统不会追踪这些变化。如果你通过
this.$refs.someElement.textContent = 'New Text'改变了内容,Vue的数据data或props并不会随之更新,也不会触发Vue的重新渲染。如果你的DOM操作最终需要反映到Vue的数据模型上,或者需要触发Vue的后续渲染,你可能需要重新审视你的方法,看看是否可以通过数据绑定来实现。
总的来说,mounted 是你与真实DOM“亲密接触”的绝佳时机。只要记住通过 ref 安全地访问元素,并在离开时清理好现场,你就能充分利用它的强大功能。
好了,本文到此结束,带大家了解了《Vuemounted生命周期详解》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多文章知识!
Redis布隆过滤器防穿透原理详解
- 上一篇
- Redis布隆过滤器防穿透原理详解
- 下一篇
- PHP单例模式详解与实战案例
-
- 文章 · 前端 | 3分钟前 |
- 箭头函数技巧与传统函数对比解析
- 412浏览 收藏
-
- 文章 · 前端 | 5分钟前 |
- v-for指令作用及常见使用场景
- 222浏览 收藏
-
- 文章 · 前端 | 6分钟前 | JavaScript 断点 HTML调试 VisualStudio 浏览器开发工具
- VS调试HTML代码技巧全解析
- 496浏览 收藏
-
- 文章 · 前端 | 6分钟前 |
- JS内存泄漏检测与解决技巧
- 430浏览 收藏
-
- 文章 · 前端 | 8分钟前 |
- JavaScript数组排序实战技巧
- 430浏览 收藏
-
- 文章 · 前端 | 13分钟前 | 区别 CSS动画 Transition @keyframes 触发方式
- CSS过渡与动画区别详解
- 415浏览 收藏
-
- 文章 · 前端 | 14分钟前 |
- CSS卡片翻转动画实现教程
- 492浏览 收藏
-
- 文章 · 前端 | 15分钟前 |
- CSS卡片悬停效果:translate与transition教程
- 164浏览 收藏
-
- 文章 · 前端 | 16分钟前 |
- CSSGrid实现自适应导航栏教程
- 231浏览 收藏
-
- 文章 · 前端 | 21分钟前 |
- CSS过渡实现浮动提示框动画:opacity与transform结合使用
- 111浏览 收藏
-
- 文章 · 前端 | 23分钟前 |
- 编码解码错误怎么解决?
- 173浏览 收藏
-
- 文章 · 前端 | 30分钟前 |
- WebAssembly引用类型与JS对象交互技巧
- 223浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 3176次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 3388次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 3417次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 4522次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 3796次使用
-
- JavaScript函数定义及示例详解
- 2025-05-11 502浏览
-
- 优化用户界面体验的秘密武器:CSS开发项目经验大揭秘
- 2023-11-03 501浏览
-
- 使用微信小程序实现图片轮播特效
- 2023-11-21 501浏览
-
- 解析sessionStorage的存储能力与限制
- 2024-01-11 501浏览
-
- 探索冒泡活动对于团队合作的推动力
- 2024-01-13 501浏览

