created 和 mounted 是 Vue 组件生命周期中两个非常重要的钩子函数。它们的主要区别在于执行时机和可操作的资源。
一、核心区别概览
| 特性 | created | mounted |
|---|---|---|
| 执行时机 | 实例创建完成后,数据观测、计算属性、方法等已配置好 | 挂载完成后,DOM 已插入文档 |
| DOM 可用性 | ❌ 不可访问真实 DOM | ✅ 可以访问真实 DOM |
| 适用场景 | 初始化数据、发送 API 请求、设置监听 | 操作 DOM、初始化第三方库、访问元素尺寸 |
| SSR(服务端渲染) | ✅ 可执行 | ❌ 不在服务端执行 |
二、详细解析
1. created 钩子
- 触发时机:
- Vue 实例(或组件)创建完成。
- 数据观测 (data observer)、属性和方法的运算、
watch/event事件回调都已配置完成。 - 但此时组件尚未挂载到 DOM 树上。
- 可以做什么:
- 初始化数据(虽然
data()已执行,但可在此进行复杂初始化)。 - 发起API 请求获取数据(推荐)。
- 设置定时器、事件监听器(注意在
beforeUnmount中清理)。 - 访问
this.$data、this.$props、this.$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 的可用性
created:this.$refs可能为undefined或为空对象,因为 DOM 未生成。mounted:this.$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 中:
onCreated→onCreated(仍在setup中执行)onMounted→onMounted(() => { /* ... */ })
import { onMounted, onBeforeUnmount } from 'vue'
export default {
setup() {
onMounted(() => {
console.log('组件已挂载')
// 操作 DOM
})
onBeforeUnmount(() => {
// 清理工作
})
}
}
✅ 总结
created:组件“出生”了,数据有了,但看不见(DOM 未挂载)。- 适合:数据初始化、网络请求。
mounted:组件“出生并出现在页面上”,可以看到并操作它。- 适合:DOM 操作、第三方库初始化。
🎯 一句话口诀:
- 数据请求放
created,- DOM 操作放
mounted。
THE END

