new ResizeObserver 是什么?没用过
很好,这个正是你现在这个场景的关键知识点。
🧠 ResizeObserver 是什么?
ResizeObserver 是浏览器提供的原生 API, 用于 —— 监听某个 DOM 元素“自身尺寸”变化。
它解决的就是你现在的问题:
页面布局变了,但窗口尺寸没变,组件却需要重新计算大小
典型场景:
| 场景 | window.resize 能监听吗 | ResizeObserver 能监听吗 |
|---|---|---|
| Splitpanes 拖动 | ❌ | ✅ |
| 侧边栏折叠展开 | ❌ | ✅ |
| Tab 切换显示隐藏 | ❌ | ✅ |
| Dialog 打开 | ❌ | ✅ |
| 浏览器窗口变化 | ✅ | ✅ |
📦 一句话理解
window.resize 监听“浏览器变大变小” ResizeObserver 监听“某个盒子变大变小”
ECharts 需要的是 盒子大小变化,不是浏览器大小变化。
🔧 基础用法(超简单)
const observer = new ResizeObserver(entries => {
console.log('尺寸变了', entries[0].contentRect.width, entries[0].contentRect.height)
})
observer.observe(dom元素)
🧩 放到你的 ECharts 里
<template>
<div ref="chartRef" class="chart"></div>
</template>
<script setup>
import * as echarts from 'echarts'
import { ref, onMounted, onBeforeUnmount } from 'vue'
const chartRef = ref(null)
let chartInstance = null
let resizeObserver = null
onMounted(() => {
chartInstance = echarts.init(chartRef.value)
chartInstance.setOption(option)
// 👇 监听图表容器尺寸变化
resizeObserver = new ResizeObserver(() => {
chartInstance.resize()
})
resizeObserver.observe(chartRef.value)
})
onBeforeUnmount(() => {
resizeObserver?.disconnect()
chartInstance?.dispose()
})
</script>
<style>
.chart {
width: 100%;
height: 100%;
}
</style>
📌 你可以把它理解成
👂 “DOM 尺寸监听器”
只要这个元素因为布局变化而变宽/变高,它就会通知你。
❓兼容性要担心吗?
不用担心,主流浏览器早就支持:
- Chrome ✅
- Edge ✅
- Firefox ✅
- Safari ✅
如果是非常老的浏览器(IE),才需要 polyfill,但你这个项目环境不用考虑。
🎯 结论
在 可拖拽布局(splitpanes)、折叠侧边栏、弹窗、tab切换 里:
❌ 不要只写 window.resize ✅ 一定要加 ResizeObserver
这是现代前端处理图表自适应的标准做法。
他怎么知道我监听的哪个盒子呢?
好问题,这正是 ResizeObserver 的工作原理核心。
🧠 它怎么知道你监听的是哪个盒子?
答案就一句话:
你把哪个 DOM 元素“交给它”,它就只监听那个元素
是你手动“注册”的,不是它自己猜的。
🔧 关键代码在这句
这句话的真实含义是:
👉 “帮我盯着 chartRef 这个 DOM,只要它尺寸变化就通知我”
📦 运行流程拆解
第一步:你告诉它目标是谁
浏览器内部就会建立一种类似:
第二步:DOM 尺寸发生变化
比如:
- splitpanes 拖动
- sidebar 收起
- 父容器 flex 改变
- display:none → block
浏览器布局引擎发现:
⚠️ 这个 DOM 盒子的 contentRect 变了
于是把变化信息打包给你
第三步:callback 收到“变更报告”
const observer = new ResizeObserver(entries => {
entries.forEach(entry => {
console.log(entry.target) // 哪个元素变了
console.log(entry.contentRect) // 新的尺寸
})
})
entry.target 就是你 observe 的那个 DOM。
🧩 可以同时监听多个盒子
observer.observe(chartRef.value)
observer.observe(otherRef.value)
observer.observe(sidebarRef.value)
谁变了,entries 里就会出现谁。
📐 contentRect 是什么?
就是 元素内容区域的新宽高(不含 margin)
这也是 ECharts resize() 需要的尺寸依据。
🎯 所以本质是
ResizeObserver 并不是“全局监听”
而是:
📝 你把某个 DOM 的“尺寸变化订阅权”交给浏览器 浏览器负责在布局阶段检测尺寸是否变化 一旦变化就回调你
🚀 对比 window.resize
| 监听方式 | 监听对象 | 触发条件 |
|---|---|---|
| window.addEventListener('resize') | 浏览器窗口 | 浏览器大小变化 |
| ResizeObserver.observe(el) | 某个 DOM 元素 | 这个元素的盒子大小变化 |
一句话总结
ResizeObserver 不“找”盒子,是你“指定”它盯哪个盒子。
你给谁 observe(),它就只看谁 👌