跳转至

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 元素“交给它”,它就只监听那个元素

是你手动“注册”的,不是它自己猜的。


🔧 关键代码在这句

resizeObserver.observe(chartRef.value)

这句话的真实含义是:

👉 “帮我盯着 chartRef 这个 DOM,只要它尺寸变化就通知我”


📦 运行流程拆解

第一步:你告诉它目标是谁

const observer = new ResizeObserver(callback)
observer.observe(目标DOM)

浏览器内部就会建立一种类似:

监听列表:
- chartRef DOM  → 尺寸变化时触发 callback

第二步: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 是什么?

entry.contentRect.width
entry.contentRect.height

就是 元素内容区域的新宽高(不含 margin)

这也是 ECharts resize() 需要的尺寸依据。


🎯 所以本质是

ResizeObserver 并不是“全局监听”

而是:

📝 你把某个 DOM 的“尺寸变化订阅权”交给浏览器 浏览器负责在布局阶段检测尺寸是否变化 一旦变化就回调你


🚀 对比 window.resize

监听方式 监听对象 触发条件
window.addEventListener('resize') 浏览器窗口 浏览器大小变化
ResizeObserver.observe(el) 某个 DOM 元素 这个元素的盒子大小变化

一句话总结

ResizeObserver 不“找”盒子,是你“指定”它盯哪个盒子。

你给谁 observe(),它就只看谁 👌

评论