Vue 3 中监听元素大小变化应使用 ResizeObserver API:①直接在 setup 中用 onMounted 创建并 observe,onBeforeUnmount 断开;②封装为 useResizeObserver 组合式函数支持响应式目标切换;③定义 v-resize 指令全局复用;注意 contentRect 不含 padding/border,IE 需降级轮询。

Vue 3 中监听元素大小变化,不能靠 window.resize,因为窗口没动、元素自己撑高或缩窄时它根本不会触发。真正该用的是浏览器原生的 ResizeObserver API,它专为监听单个或多个 DOM 元素的宽高变化而设计,响应及时、性能友好,且天然适配 Vue 的响应式逻辑。
直接在 setup 中使用 ResizeObserver 实例
适合简单场景,比如只监听一个容器、回调逻辑轻量:
- 在
onMounted中创建ResizeObserver,传入回调函数,里面能拿到每个 entry 的contentRect(含width和height) - 用
ref拿到目标元素(如<div ref="targetRef">),调用 <code>observer.observe(targetRef.value) - 务必在
onBeforeUnmount中调用observer.disconnect(),避免内存泄漏 - 函数接收
target(可以是 Ref、HTMLElement 或数组)和callback,内部自动处理多目标、目标变更、组件卸载清理 - 利用
computed动态解析 target 值,配合watch监听 targets 变化,变化时先disconnect再重新observe - 返回
{ start, stop }方法,方便手动控制观察启停,比如弹窗关闭后暂停监听 - 用
WeakMap存储 DOM 元素与 handler 的映射,避免强引用导致内存问题 - 全局共享一个
ResizeObserver实例(节省资源),在mounted钩子中调用observe(el)并存入映射 - 模板中直接写
<div v-resize="handleResize">,回调参数就是 <code>entry.contentRect,简洁干净注意事项和常见避坑点
实际用起来有几个关键细节容易出错:
-
contentRect.width/height是 content box 尺寸,不含 padding 和 border;如需包含边框,可读borderBoxSize(注意兼容性) - Chrome 控制台可能报
ResizeObserver loop completed with undelivered notifications—— 这是警告不是错误,通常因频繁重绘或嵌套监听触发,不影响功能,开发期可忽略或隐藏 overlay - IE 完全不支持,若需兼容旧浏览器,得降级为定时轮询 +
getBoundingClientRect,但仅作兜底,不推荐作为主方案
-
封装成组合式函数 useResizeObserver
这是推荐做法,复用性高、逻辑清晰、支持响应式目标切换:
从零开始编排 SpringBoot+Vue 全栈项目工作流,适用于新建全栈项目或完整脚手架请求,触发后依次调用 product‑spec‑builder(需求调研)等模块。
定义自定义指令 v-resize
适合全局高频使用,写一次、处处绑定,语义也更直观:
立即学习“前端免费学习笔记(深入)”;

















