当前位置: 首页 > web >正文

ResizeObserver 解决 echarts渲染不出来,内容宽度为 0的问题

【问题场景】 vue项目,封装了echarts相关的图表组件,在父组件中引入这些组件,图表宽度由父组件中的包裹元素决定,而这些包裹元素的宽度不固定,是按比例计算来的,页面刷新时,偶现部分图表渲染不出来,F12定位发现 这些图表的内容宽度是 0。

在这里插入图片描述

【原先的代码】
1、父组件

<template><div class="chart-wrapper"><div class="chart-card margin-right-16"><PieChart v-bind="pieChart" /></div><div class="chart-card margin-right-16"><LineChart v-bind="lineChart" /></div><div class="chart-card"><BarChart v-bind="barChart" /></div></div>
</template><script setup>import { ref, onMounted } from 'vue'import PieChart from '@/components/Charts/PieChart'import LineChart from '@/components/Charts/LineChart'import BarChart from '@/components/Charts/BarChart'const pieChart = ref({id: 'pieChart',chartStyle: {height: '180px'}})const fetchPieData = () => {...pieChart.value = {id: 'pieChart',chartStyle: {height: '180px'},title: ...legend: ...series: ...}}const lineChart = const fetchLineData = const barChart = const fetchBarData = onMounted(() => {fetchPieData()fetchLineData()fetchBarData()})
</script><style lang="scss" scoped>.chart-wrapper {width: 100%;.chart-card {display: inline-block;width: calc((100% - 32px) / 3);height: 240px;}.margin-right-16 {margin-right: 16px;}}
</style>

2、echarts图表组件 BarChart.vue

<template><div :id="id" :style="chartStyle" class="chart-contianer"></div>
</template><script setup>
import { onMounted, nextTick, watch } from 'vue'
import * as echarts from 'echarts'const props = defineProps({id: {type: String,default: ''},chartStyle: {type: Object,default: () => ({})},xAxis: ...yAxis: ...series: ...
})const drawChart = async () => {await nextTick()const container = document.getElementById(props.id)const chartsDom = echarts.init(container)container.removeAttribute('_echarts_instance_')const option = {grid: ...tooltip: ...legend: ...color: ...xAxis: ...yAxis: ...series: ...}chartsDom.setOption(option)
}watch(() => props.seriesData, (newVal) => {if (newVal) drawChart()
}, { deep: true })onMounted(() => {drawChart()
})</script><style lang="scss" scoped>.chart-contianer {width: 100%;height: 100%;}
</style>

【错误的思考方向】 echarts组件的数据获取是在父组件的 onMounted 中进行的,父组件 DOM 节点挂载完成的时候子组件应该也挂载完成了,而且子组件中还有 watch 监听图表数据的变化可以重新渲染,不应该会出现获取不到容器元素的问题。

【原因分析】 其实echarts能渲染,表示容器元素是存在的,所以不是获取不到容器元素的问题,而是容器元素的宽度还未撑开。真正的原因是:即使 DOM 挂载完成,浏览器的 layout/reflow 还未完成,导致子元素 size 还没确定。即 DOM 挂载完成不代表渲染完成所以什么把数据获取放在 onMounted中进行、获取数据之后在 nextTick 之后渲染图表,都没有用。

【解决方法】 监听容器元素的尺寸变化,即时重新渲染图表,这里可以用 ResizeObserver 。具体API参考 ResizeObserver

【修改子组件代码】

<template><div :id="id" :style="chartStyle" class="chart-contianer"></div>
</template><script setup>
import { onMounted, onBeforeUnmount, nextTick, watch } from 'vue'
import * as echarts from 'echarts'...// ——————监听容器元素 start——————
// 创建一个 ResizeObserver实例
const observer = new ResizeObserver(entries => {entries.forEach(entry => {if (entry?.target?.id === props.id) drawChart()})
})onMounted(() => {// 监听指定元素observer.observe(document.getElementById(props.id))drawChart()
})onBeforeUnmount(() => {observer.unobserve(document.getElementById(props.id))
})
// ——————监听容器元素 end——————
</script><style lang="scss" scoped>.chart-contianer {width: 100%;height: 100%;}
</style>
http://www.xdnf.cn/news/9565.html

相关文章:

  • 无法发布到PowerBI?试试拆分它
  • 回头看,FPGA+RK3576方案的功耗性能优势
  • 设计模式-单例模式
  • 理解 C++ 多态:概念、实现方式与实战示例
  • 密钥管理系统在存储加密场景中的深度实践:以TDE透明加密守护文件服务器安全
  • VC++和python从哪一年开始支持split(字符串)非单个字符
  • 【深度学习-pytorch篇】1. Pytorch矩阵操作与DataSet创建
  • LiveGBS国标视频平台收流模式:UDP、TCP被动与TCP主动传输模式之差异剖析
  • 【系统架构设计师】2025年上半年真题论文回忆版: 论多模型数据库及应用(包括解题思路和参考素材)
  • python--=的用法
  • 小白的进阶之路系列之四----人工智能从初步到精通pytorch自定义数据集下
  • 【每天一个知识点】LangChain
  • 针对Python开发的工具推荐及分析,涵盖集成开发环境(IDE)、轻量级工具、在线开发平台、代码管理工具等)
  • 智能手表怎么申请欧盟EN 18031认证
  • 主流 AI IDE 之一的 Windsurf 介绍
  • MySQL 数据迁移Postgresql(openGuass) 之 pg_chameleon
  • BGP实验报告
  • SQLiteStudio - 免费开源、轻量高效,跨平台的 SQLite 数据库管理工具,代替 Navicat for SQLite
  • 【已解决】windows gitbash 出现CondaError: Run ‘conda init‘ before ‘conda activate‘
  • 深入探讨集合与数组转换方法
  • 如何实现电竞比赛的实时直播?
  • 如何收集Oracle DB SQL Monitor报告
  • JavaScript性能优化实战大纲
  • win10 pip安装插件包报错:No matching distribution found for pytest-xlsx
  • nohup命令基本用法
  • delta 流响应
  • 华为手机用的时间长了,提示手机电池性能下降,需要去换电池吗?平时要怎么用能让电池寿命长久一些?
  • Android Compose开发架构选择指南:单Activity vs 多Activity
  • Nginx代理SSL 到Spring boot
  • 多相电机驱动控制学习(2)——基于双dq的双三相PMSM学习(考虑互感/交叉耦合)