onUnmounted 是组件卸载前执行清理逻辑的标准方式,需手动清理定时器、全局事件监听器、第三方实例、未完成 fetch 请求及 watch 监听器,防止内存泄漏。

在 Vue Composition API 中,onUnmounted 是组件卸载前执行清理逻辑的标准方式。它必须在 setup 函数内调用,且只在组件从 DOM 中完全移除、所有子组件也已卸载后触发——这是释放资源的最后可靠时机。
哪些资源必须手动清理?
Vue 不会自动回收你主动创建的外部副作用。以下几类操作若不清理,极易引发内存泄漏或异常行为:
- 通过
setInterval或setTimeout启动的定时器 - 使用
window.addEventListener、document.addEventListener绑定的全局事件监听器 - 第三方库实例(如 ECharts、Mapbox、WebSocket 连接)
- 未完成的 fetch 请求(需配合
AbortController) - 手动调用
watch或store.$subscribe创建的监听器(未用其返回的 stop 函数时)
定时器清理:最常见场景
直接在 onUnmounted 中清除引用即可,注意避免重复调用或清除已销毁的 timer:
import { onMounted, onUnmounted } from 'vue'
<p>export default {
setup() {
let timer = null</p><pre class='brush:php;toolbar:false;'>onMounted(() => {
timer = setInterval(() => {
console.log('每秒执行一次')
}, 1000)
})
onUnmounted(() => {
if (timer) {
clearInterval(timer)
timer = null
}
})} }
取消网络请求:用 AbortController
fetch 支持中断机制,应在组件挂载时创建控制器,并在卸载时 abort:
递归分析 Vue 项目组件依赖,从入口文件生成组件层级图,支持 Vue 2/3,输出组件名、文件路径和属性。适用于分析组件结构、排查依赖或了解项目架构。
立即学习“前端免费学习笔记(深入)”;
import { onMounted, onUnmounted } from 'vue'
<p>export default {
setup() {
let controller = null</p><pre class='brush:php;toolbar:false;'>onMounted(async () => {
controller = new AbortController()
try {
const res = await fetch('/api/data', {
signal: controller.signal
})
const data = await res.json()
// 处理数据...
} catch (err) {
if (err.name === 'AbortError') return // 请求被取消,忽略
console.error(err)
}
})
onUnmounted(() => {
if (controller) controller.abort()
})} }
解绑全局事件与销毁第三方实例
例如监听窗口大小变化,或初始化 ECharts 图表:
import { onMounted, onUnmounted, ref } from 'vue'
import * as echarts from 'echarts'
<p>export default {
setup() {
const chartRef = ref(null)
let chartInstance = null</p><pre class='brush:php;toolbar:false;'>onMounted(() => {
const dom = chartRef.value
if (dom) {
chartInstance = echarts.init(dom)
chartInstance.setOption({ /* 配置 */ })
}
const handleResize = () => chartInstance?.resize()
window.addEventListener('resize', handleResize)
// 保存监听器引用,便于后续移除
chartRef.handleResize = handleResize
})
onUnmounted(() => {
if (chartInstance) {
chartInstance.dispose() // ECharts 必须显式 dispose
chartInstance = null
}
if (chartRef.value?.handleResize) {
window.removeEventListener('resize', chartRef.value.handleResize)
}
})} }
watch 的清理:优先用返回值,次选 onUnmounted
推荐写法是直接使用 watch 返回的 stop 函数,它会在组件卸载时自动调用;但如果 watch 在 setup 外部创建,或需要统一管理,也可放入 onUnmounted:
import { watch, onUnmounted } from 'vue'
<p>export default {
setup() {
const stopWatch = watch(
() => state.count,
(newVal) => console.log('count changed:', newVal)
)</p><pre class='brush:php;toolbar:false;'>// 方式一:推荐 —— 无需 onUnmounted,stop 自动触发
// 方式二:手动控制 —— 若需延迟停止或条件停止,可保留 stop 并在 onUnmounted 中调用
onUnmounted(() => {
stopWatch()
})} }
不复杂但容易忽略

















