ECharts弹窗白屏主因是容器未挂载就init、canvas不可绘或实例复用;应延迟初始化至弹窗显示后,确保DOM存在且可绘,销毁旧实例并避免canvas-id重复。

弹窗中 ECharts 容器未挂载就 init 导致白屏
最常见的情况是:弹窗用 v-if 或 show 控制显隐,但图表初始化逻辑写在 onReady 或 mounted 里——此时 DOM 还没插入(弹窗未打开),echarts.init() 拿到的 document.getElementById() 或 this.$refs.xxx 是 null,后续调用 setOption 也无效。
解决关键是「等弹窗真实渲染完成后再初始化」:
- 把图表初始化逻辑从生命周期钩子,挪到弹窗显示后的回调里,比如
uni.showModal的success、自定义弹窗组件的@show事件,或nextTick+setTimeout(0)双保险 - 若用
renderjs,确保:prop绑定的数据在弹窗显示后才更新,触发:change:prop回调 - 避免在
v-if="false"的父节点内提前执行echarts.init(),哪怕加了if (el)判断也不够——V8 引擎下 DOM 根本不存在,document.getElementById会直接报错中断脚本
弹窗层级或 visibility 隐藏导致 canvas 不绘制
iOS 和安卓真机上,ECharts 依赖 canvas 渲染。如果弹窗容器有 visibility: hidden、opacity: 0、display: none(哪怕只是瞬时),或被更高 z-index 元素遮挡,canvas 就不会触发绘制流程,表现为「有容器、无图表」。
检查点:
- 弹窗打开后,用 Safari(iOS)或 Chrome(安卓)远程调试,查看该
div是否真实出现在 DOM 中,且offsetWidth/offsetHeight> 0 - 确认弹窗样式没写
overflow: hidden且裁掉了 canvas;transform缩放为 0 或负值也会让 canvas 失效 -
uni-app 的
uni-popup等组件默认用transition动画,动画过程中 DOM 已存在但可能处于不可绘状态,建议初始化延迟到transitionend后
renderjs 下弹窗中多次 init 导致 canvas 冲突
用 lang="renderjs" 是 APP 端正确方案,但容易忽略一个细节:每次弹窗打开都调用 echarts.init(canvas),而 canvas 实例未销毁,会导致「重复 init 同一个 canvas」——ECharts 内部会报 Canvas is already initialized 警告,后续 setOption 失效。
ECharts 图表大师。根据用户数据和业务上下文,自动设计并生成专业的 ECharts 可视化图表。使用场景:(1) 用户提供表格/JSON/CSV 数据需要可视化,(2) 用户说"帮我做个图"、"画个图表",(3) 需要将查询结果可视化展示。
稳妥做法:
- 在 renderjs 模块中缓存 chart 实例,每次 init 前先
if (myChart) myChart.dispose() - 或改用
echarts.getInstanceByDom()获取已有实例,避免重复创建 - 主 script 中控制「只在第一次弹窗时传入 option」,后续仅通过
:change:prop更新数据,不重建 chart
微信小程序弹窗里用 uni-ec-canvas 报 canvas-id 重复
小程序环境必须用 uni-ec-canvas 组件,但它依赖 canvas-id 全局唯一。如果多个弹窗共用同一个 canvas-id(比如都写死为 "myChart"),后打开的弹窗会覆盖前一个,导致前一个白屏。
解决方案:
- 每个弹窗实例生成唯一
canvas-id,例如拼接时间戳或随机数:canvas-id="chart-{{+new Date()}}" - 确保
uni-ec-canvas的:ec对象每次都是新引用(不能复用同一对象),否则init方法不会重新执行 - 在弹窗
hide时手动调用chart.dispose(),释放 canvas 资源,避免内存泄漏和 id 冲突
真正卡住人的往往不是「怎么画图」,而是「图在哪画」——弹窗的 DOM 生命周期、渲染上下文、canvas 实例管理,三者错一个,图表就静默消失。别急着改 option,先确认容器是否真实存在、是否可绘、是否被复用。










