面试题:Vue 中 created 和 mounted 生命周期钩子有什么区别?

createdmounted 是 Vue 组件生命周期中两个非常重要的钩子函数。它们的主要区别在于执行时机可操作的资源


一、核心区别概览

特性createdmounted
执行时机实例创建完成后,数据观测、计算属性、方法等已配置好挂载完成后,DOM 已插入文档
DOM 可用性不可访问真实 DOM可以访问真实 DOM
适用场景初始化数据、发送 API 请求、设置监听操作 DOM、初始化第三方库、访问元素尺寸
SSR(服务端渲染)✅ 可执行❌ 不在服务端执行

二、详细解析

1. created 钩子

  • 触发时机
    • Vue 实例(或组件)创建完成
    • 数据观测 (data observer)、属性和方法的运算、watch/event 事件回调都已配置完成。
    • 但此时组件尚未挂载到 DOM 树上
  • 可以做什么
    • 初始化数据(虽然 data() 已执行,但可在此进行复杂初始化)。
    • 发起API 请求获取数据(推荐)。
    • 设置定时器、事件监听器(注意在 beforeUnmount 中清理)。
    • 访问 this.$datathis.$propsthis.$refs(但 $refs 可能为空,因 DOM 未挂载)。
  • 示例
  export default {
    data() {
      return {
        userList: []
      }
    },
    async created() {
      console.log('组件已创建')
      console.log(this.$el) // undefined,DOM 尚未生成

      // ✅ 推荐:在此发起数据请求
      try {
        const res = await fetch('/api/users')
        this.userList = await res.json()
      } catch (err) {
        console.error('请求失败:', err)
      }
    }
  }

2. mounted 钩子

  • 触发时机
    • 组件被挂载到 DOM 后。
    • this.$el 现在有了真实的 DOM 元素。
    • 子组件也已挂载完成(除非有异步组件)。
  • 可以做什么
    • 操作真实 DOM(如获取元素尺寸、位置)。
    • 初始化依赖 DOM 的第三方库(如 Chart.js、Swiper、地图组件)。
    • 设置 DOM 事件监听器(原生事件)。
    • 执行需要 DOM 存在的动画。
  • 示例
  export default {
    mounted() {
      console.log('组件已挂载')
      console.log(this.$el) // ✅ 现在可以访问真实 DOM 元素

      // ✅ 初始化图表
      this.chart = new Chart(this.$el.querySelector('#myChart'), {
        type: 'bar',
        data: { /* ... */ }
      })

      // ✅ 获取元素高度
      const height = this.$el.offsetHeight
      console.log('组件高度:', height)

      // ✅ 设置原生 DOM 事件
      this.$el.addEventListener('click', this.handleClick)
    },
    beforeUnmount() {
      // 清理事件监听器
      this.$el.removeEventListener('click', this.handleClick)
      // 销毁图表
      if (this.chart) this.chart.destroy()
    }
  }

三、关键注意事项

1. 服务端渲染(SSR)差异

  • created:在服务端和客户端都会执行
  • mounted仅在客户端执行,服务端不会触发。

因此,与 DOM 相关的操作不能放在 created 中期望在 SSR 时生效。

2. this.$refs 的可用性

  • createdthis.$refs 可能为 undefined 或为空对象,因为 DOM 未生成。
  • mountedthis.$refs 已完全填充,可以安全访问。
// ❌ 错误:在 created 中访问 $refs 可能失败
created() {
  console.log(this.$refs.myInput) // undefined
}

// ✅ 正确:在 mounted 中访问
mounted() {
  console.log(this.$refs.myInput) // <input> 元素
}

3. 异步组件的影响

如果组件包含异步组件(defineAsyncComponent),mounted 只有在所有子组件都挂载完成后才触发。


四、选择建议:何时使用?

需求推荐钩子
发送 API 请求获取数据created
初始化数据状态created
操作 DOM 元素mounted
初始化依赖 DOM 的第三方库mounted
设置原生 DOM 事件监听器mounted
需要在服务端执行的逻辑created
获取元素尺寸、位置mounted

五、Vue 3 中的变化

在 Vue 3 的 Composition API 中:

  • onCreatedonCreated(仍在 setup 中执行)
  • onMountedonMounted(() => { /* ... */ })
import { onMounted, onBeforeUnmount } from 'vue'

export default {
  setup() {
    onMounted(() => {
      console.log('组件已挂载')
      // 操作 DOM
    })

    onBeforeUnmount(() => {
      // 清理工作
    })
  }
}

✅ 总结

  • created:组件“出生”了,数据有了,但看不见(DOM 未挂载)。
  • 适合:数据初始化、网络请求
  • mounted:组件“出生并出现在页面上”,可以看到并操作它。
  • 适合:DOM 操作、第三方库初始化

🎯 一句话口诀

  • 数据请求放 created
  • DOM 操作放 mounted
THE END
喜欢就支持一下吧
点赞11 分享