/* ECharts 生命周期复用:init / setOption / resize / dispose 统一 */ import { onMounted, onUnmounted, type Ref } from 'vue' import * as echarts from 'echarts' export function useChart(el: Ref) { let chart: echarts.ECharts | null = null let ro: ResizeObserver | null = null function ensureChart(): void { if (!chart && el.value) chart = echarts.init(el.value) } function setOption(option: echarts.EChartsCoreOption): void { ensureChart() chart?.setOption(option, true) // 数据通常在容器布局完成后才到(父组件异步拉取),此处同步一次尺寸, // 避免 canvas 停在 init 时的窄宽(tab/初始化偏早导致)。 chart?.resize() } function resize(): void { chart?.resize() } onMounted(() => { ensureChart() // ResizeObserver: 容器拿到真实宽度 / tab 切换 / 窗口变化时自动 resize if (el.value && typeof ResizeObserver !== 'undefined') { ro = new ResizeObserver(() => chart?.resize()) ro.observe(el.value) } window.addEventListener('resize', resize) }) onUnmounted(() => { window.removeEventListener('resize', resize) ro?.disconnect() chart?.dispose() chart = null }) return { setOption } }