当前位置:首页 > 文章列表 > 文章 > 前端 > Vuemounted生命周期全解析

Vuemounted生命周期全解析

2025-08-03 08:12:28 0浏览 收藏

`mounted`钩子是Vue组件生命周期中至关重要的一环,它在组件挂载到DOM后立即触发,标志着组件已完全呈现在用户眼前。此阶段允许执行依赖DOM的操作,例如初始化ECharts、地图SDK等第三方库,直接操作DOM元素(推荐使用`ref`),发送依赖DOM尺寸的数据请求,以及设置全局事件监听器(务必在`beforeUnmount`中清理以防内存泄漏)。与`created`不同,`mounted`拥有DOM访问权限,可访问`this.$el`和`this.$refs`,适用于需要真实DOM的逻辑。数据请求通常优先放置在`created`中以提升性能,仅当依赖DOM时才选择`mounted`。需要注意的是,在SSR(服务器端渲染)场景下,`mounted`钩子不会执行,因此需要考虑同构兼容性。掌握`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不执行,需注意同构兼容性。

vue 中 mounted 生命周期作用 vue 中 mounted 生命周期的使用场景

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

vue 中 mounted 生命周期作用 vue 中 mounted 生命周期的使用场景

解决方案

在我看来,理解 mounted 钩子,就像理解一个舞台剧的开幕。created 阶段是演员在后台准备,剧本都捋顺了,数据也到位了。但真正的“表演”——也就是组件在用户屏幕上呈现——得等到 mounted。在这个时刻,你的组件模板已经被编译成真实的HTML元素,并且被插入到了文档流中。这意味着,你终于可以安全地访问到 this.$el(组件的根DOM元素)以及通过 ref 标记的任何子元素了。

为什么这很重要?因为很多前端操作,尤其是与第三方库交互,或者需要测量、绘制DOM的场景,都必须在DOM元素实际存在后才能进行。比如,你想用ECharts画个图,或者用D3.js操作SVG,这些库都需要一个真实的DOM容器来承载它们的输出。如果你在 created 里就尝试这些,那多半会报错,因为容器还没影儿呢。

vue 中 mounted 生命周期作用 vue 中 mounted 生命周期的使用场景

我个人在使用 mounted 时,最常见的场景就是:

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

mountedcreated 的区别:何时选择谁?

说实话,这是个老生常谈的问题,但确实是理解Vue生命周期的核心。简单来说:

vue 中 mounted 生命周期作用 vue 中 mounted 生命周期的使用场景
  • 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 里:

  1. 数据请求依赖DOM尺寸或属性:比如,你需要根据组件渲染后的实际宽度来决定请求不同分辨率的图片,或者为图表组件获取数据时,需要先初始化图表容器才能知道其可用的绘制区域大小。这种情况下,mounted 是你唯一的选择,因为只有这时DOM才真正可用。
  2. 与第三方库结合:有些第三方库可能需要先在 mounted 中完成初始化,然后才能通过其API发起数据请求。虽然这种情况相对少见,但确实存在。

还需要注意的是 SSR (Server-Side Rendering) 的场景。在SSR中,mounted 钩子是不会在服务器端执行的,因为它涉及到浏览器环境的DOM操作。而 created 钩子则会在服务器端执行。所以,如果你正在构建一个同构应用(Isomorphic App),并且希望数据在服务器端就能预取,那么 createdbeforeCreate (或者 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.querySelectorgetElementById:尽管它们能工作,但这种方式会使你的组件与全局DOM结构紧密耦合,降低组件的可复用性。如果页面上有多个相同组件的实例,或者DOM结构发生变化,你的选择器可能会失效或选中错误的元素。ref 机制是Vue提供的一种更安全、更局部的访问方式。
  • 清理副作用:如果你在 mounted 中添加了全局的事件监听器(比如 window.addEventListenerdocument.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的数据 dataprops 并不会随之更新,也不会触发Vue的重新渲染。如果你的DOM操作最终需要反映到Vue的数据模型上,或者需要触发Vue的后续渲染,你可能需要重新审视你的方法,看看是否可以通过数据绑定来实现。

总的来说,mounted 是你与真实DOM“亲密接触”的绝佳时机。只要记住通过 ref 安全地访问元素,并在离开时清理好现场,你就能充分利用它的强大功能。

今天带大家了解了的相关知识,希望对你有所帮助;关于文章的技术知识我们会一点点深入介绍,欢迎大家关注golang学习网公众号,一起学习编程~

Linux流量异常分析技巧分享Linux流量异常分析技巧分享
上一篇
Linux流量异常分析技巧分享
AI视频工具推荐:做虾仁动漫必备神器
下一篇
AI视频工具推荐:做虾仁动漫必备神器
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    542次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    511次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    498次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    484次学习
查看更多
AI推荐
  • 千音漫语:智能声音创作助手,AI配音、音视频翻译一站搞定!
    千音漫语
    千音漫语,北京熠声科技倾力打造的智能声音创作助手,提供AI配音、音视频翻译、语音识别、声音克隆等强大功能,助力有声书制作、视频创作、教育培训等领域,官网:https://qianyin123.com
    100次使用
  • MiniWork:智能高效AI工具平台,一站式工作学习效率解决方案
    MiniWork
    MiniWork是一款智能高效的AI工具平台,专为提升工作与学习效率而设计。整合文本处理、图像生成、营销策划及运营管理等多元AI工具,提供精准智能解决方案,让复杂工作简单高效。
    92次使用
  • NoCode (nocode.cn):零代码构建应用、网站、管理系统,降低开发门槛
    NoCode
    NoCode (nocode.cn)是领先的无代码开发平台,通过拖放、AI对话等简单操作,助您快速创建各类应用、网站与管理系统。无需编程知识,轻松实现个人生活、商业经营、企业管理多场景需求,大幅降低开发门槛,高效低成本。
    110次使用
  • 达医智影:阿里巴巴达摩院医疗AI影像早筛平台,CT一扫多筛癌症急慢病
    达医智影
    达医智影,阿里巴巴达摩院医疗AI创新力作。全球率先利用平扫CT实现“一扫多筛”,仅一次CT扫描即可高效识别多种癌症、急症及慢病,为疾病早期发现提供智能、精准的AI影像早筛解决方案。
    102次使用
  • 智慧芽Eureka:更懂技术创新的AI Agent平台,助力研发效率飞跃
    智慧芽Eureka
    智慧芽Eureka,专为技术创新打造的AI Agent平台。深度理解专利、研发、生物医药、材料、科创等复杂场景,通过专家级AI Agent精准执行任务,智能化工作流解放70%生产力,让您专注核心创新。
    102次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码