Vue 3 中窗口滚动监听需在 onMounted 注册、onUnmounted 注销,确保监听器不残留;监听函数须为具名方法且引用一致,推荐封装为 useScrollPosition 组合式函数。

在 Vue 3 中实现窗口滚动监听,核心是“挂载时注册、卸载前注销”,确保事件监听器不残留、不重复、不泄漏。关键不在能不能加,而在加得准、删得净。
注册监听:用 onMounted 绑定 scroll 事件
必须在 onMounted 中添加监听,此时 DOM 已就绪,window 对象可安全访问。不要用 onBeforeMount 或 setup 同步逻辑——scroll 依赖真实滚动位置,过早执行会读不到有效值。
- 监听函数需为具名方法(如
handleScroll),不能是内联箭头函数,否则解绑时无法匹配引用 - 首次滚动前可手动触发一次
handleScroll()初始化状态(比如设置初始scrollY) - 若需节流,建议在 handler 内部处理,而非包裹 addEventListener
注销监听:用 onUnmounted 移除对应监听器
onUnmounted 是唯一安全的清理时机。onUnmounted 执行时组件实例仍完整,this 或响应式变量(如 ref)都可访问;而 unmounted 钩子触发时实例已销毁,removeEventListener 很可能静默失败。
Element Plus Vue3 桌面组件库。在开发 Vue 3.x 页面时调用,使用 Element Plus 组件(如 el-button、el-input、el-form、el-table 等)。
- 移除时必须传入与绑定时完全相同的函数引用、事件类型和选项(如
{ passive: true }) - 推荐把 handler 定义在 setup 内部并用 ref 缓存,避免闭包导致引用不一致
- 注销后可将 handler 置为 null(非必需,但利于调试和 GC)
更简洁可靠的写法:封装成组合式函数
重复写 onMounted/onUnmounted 容易出错。可抽离为可复用的 useScrollPosition:
立即学习“前端免费学习笔记(深入)”;
- 接收一个 ref(如
scrollY)作为响应式目标 - 内部自动注册/注销,调用方只需
const scrollY = useScrollPosition() - 支持可选节流、被动模式(
passive: true)、指定 target(默认 window) - Vue 官方生态已有成熟实现(如
@vueuse/core的useScroll),可直接引入
常见踩坑点
这些细节不注意,轻则监听失效,重则页面卡顿:
- 在
onActivated或onUpdated里重复绑定 scroll —— 导致监听器越积越多 - 用
() => this.handleScroll()绑定,解绑时找不到同一函数引用 - 监听了 scroll 却没监听 touchmove(移动端滑动可能不触发 scroll),需按需补充
- 在 keep-alive 组件中,onUnmounted 不会触发,应改用
onDeactivated清理

















