🔍 一、onMounted()
是什么?它的核心作用
onMounted() 是 Vue 3 组合式 API 中的生命周期钩子,用于在组件挂载到 DOM 后执行逻辑。其核心作用包括:
- 访问 DOM 元素:确保 DOM 已渲染完成,可安全操作。
- 初始化副作用:如事件监听、第三方库初始化、数据请求。
- 执行一次性任务:如日志记录、性能监控埋点。
🛠️ 二、基础使用与语法
1️⃣ 基本语法
在组合式 API(<script setup>)中使用:
<script setup>
import { onMounted } from 'vue' // 定义逻辑
onMounted(() => { console.log('组件已挂载') // 访问 DOM 或初始化操作
})
</script>
2️⃣ 对比选项式 API
选项式 API 中的 mounted 钩子:
export default { mounted() { console.log('组件已挂载') }
}
3️⃣ 注册多个钩子
可多次调用 onMounted(),按注册顺序执行:
onMounted(() => { console.log('第一个挂载钩子')
}) onMounted(() => { console.log('第二个挂载钩子')
})
// 输出顺序:第一个 → 第二个
🚀 三、核心应用场景
1️⃣ 访问 DOM 元素
结合 ref() 获取模板引用:
<template> <input ref="inputRef" />
</template> <script setup>
import { ref, onMounted } from 'vue' const inputRef = ref(null) onMounted(() => { inputRef.value.focus() // DOM 已渲染,安全访问
})
</script>
2️⃣ 初始化第三方库
初始化需要 DOM 的库(如图表、地图):
import { onMounted } from 'vue'
import echarts from 'echarts' const initChart = () => { const chart = echarts.init(document.getElementById('chart')) chart.setOption({ /* ... */ })
} onMounted(initChart)
3️⃣ 发起异步数据请求
组件挂载后加载数据:
const loadData = async () => { const res = await fetch('/api/data') data.value = await res.json()
} onMounted(() => { loadData()
})
🚨 四、常见陷阱与解决方案
1️⃣ 异步操作与组件卸载竞态
问题:组件卸载后异步回调仍可能执行,导致内存泄漏或错误。
解决:使用标志变量或清理函数:
let isMounted = true onMounted(() => { fetchData().then(res => { if (isMounted) { // 处理数据 } })
}) onUnmounted(() => { isMounted = false
})
2️⃣ SSR 环境下的 DOM 访问
问题:服务端渲染时,onMounted() 不会执行,直接访问 DOM 会报错。
解决:使用 onMounted() 确保代码仅在客户端运行:
onMounted(() => { // 仅客户端执行的代码 if (typeof window !== 'undefined') { initClientOnlyLib() }
})
3️⃣ 依赖未就绪的子组件
问题:父组件onMounted 触发时,子组件可能尚未挂载。
解决:在子组件中执行逻辑,或使用 nextTick:
onMounted(() => { nextTick(() => { // 确保子组件已挂载 })
})
🔧 五、进阶技巧与最佳实践
1️⃣ 与 onUnmounted()
配合清理副作用
onMounted(() => { const timer = setInterval(() => { // 轮询任务 }, 1000) // 组件卸载时清理 onUnmounted(() => { clearInterval(timer) })
})
2️⃣ 封装可复用的挂载逻辑
使用组合式函数抽象逻辑:
// useAutoFocus.js
export function useAutoFocus(refName) { const elementRef = ref(null) onMounted(() => { if (elementRef.value) { elementRef.value.focus() } }) return { [refName]: elementRef }
} // 组件中使用
const { inputRef } = useAutoFocus('inputRef')
3️⃣ 性能优化:避免阻塞主线程
耗时操作放入 requestIdleCallback:
onMounted(() => { requestIdleCallback(() => { // 执行非关键任务 })
})
🌟 六、总结:onMounted()
使用要点
场景 | 最佳实践 |
---|---|
DOM 操作 | 结合模板 ref 访问,确保 DOM 已渲染 |
数据请求 | 处理竞态条件,及时清理异步任务 |
第三方库初始化 | 仅在客户端执行(SSR 兼容) |
副作用管理 | 使用 onUnmounted 清理监听器、定时器 |
性能敏感操作 | 拆分任务或使用 Web Worker |
📢 讨论:你在使用 onMounted() 时遇到过哪些问题?如何优化挂载时的性能?欢迎分享经验!👇