vue中绑定window事件应mounted时添加、beforedestroy/beforeunmount时移除,确保函数引用一致且一一对应,避免内存泄漏;推荐使用usewindowsize等现代组合式函数替代resize监听。

在 Vue 生命周期中绑定 window 事件,核心是“挂载时加、销毁前删”,否则容易引发内存泄漏或重复监听。关键不在能不能用,而在什么时候加、怎么删、删得干不干净。
绑定时机:mounted 是最稳妥的选择
虽然 created 阶段也能访问 window 对象,但此时 DOM 尚未挂载,若事件处理逻辑涉及 ref、元素尺寸(如 window.innerWidth)或依赖渲染后的布局,就可能取值不准或报错。mounted 确保组件已真实挂载,DOM 可用,window 对象稳定可读。
- 直接在 mounted 中调用 window.addEventListener('resize', handler)
- handler 必须是具名函数或 this 上的 methods 方法,不能是内联箭头函数
- 如果需初始化状态(如首次读取窗口宽高),也放在这里执行
解绑时机:beforeDestroy(Vue 2)或 beforeUnmount(Vue 3)不可替代
destroyed 或 unmounted 钩子执行时,组件实例已解构,this 可能为 null,window.removeEventListener 调用可能失败或静默忽略。beforeDestroy / beforeUnmount 是最后一个能安全访问 this 和响应式系统的时机,确保移除动作可靠执行。
- 必须与绑定使用同一函数引用,例如:this.handleResize,而非 () => {...}
- 解绑代码应放在 beforeDestroy(Vue 2)或 onBeforeUnmount(Vue 3 Composition API)中
- 建议在解绑后手动置空 handler 引用(非必需,但利于调试和 GC)
全局监听器回收要“一一对应”,避免残留
一个 window 事件监听器一旦绑定,就会一直存在,直到显式 remove。若组件被反复创建销毁(如路由切换、v-if 切换),而没正确解绑,监听器会越积越多,导致 resize 触发多次、性能下降甚至卡顿。
- 每个 addEventListener 都应有且仅有一个对应的 removeEventListener,参数完全一致
- 不要在多个生命周期钩子里重复绑定同一事件(比如 mounted + activated 都加 resize)
- 若使用第三方库(如 scrollmagic、intersection-observer),确认其是否自带销毁逻辑;否则需手动清理
更简洁安全的写法(Vue 2/3 均适用)
把绑定/解绑逻辑封装成可复用函数,减少重复出错。例如:
- Vue 2:用 mixin 提供 addWindowListener(event, handler),内部自动记录并统一在 beforeDestroy 清理
- Vue 3:在 setup 中用 onBeforeUnmount(() => window.removeEventListener(...)),handler 定义在作用域顶层,保证引用稳定
- 现代替代方案:优先考虑 useWindowSize() 这类组合式函数(基于 ResizeObserver),比监听 window.resize 更精准、无泄漏风险
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











