【Vue3 + ECharts 实战】正确使用 showLoading、resize 与 dispose 避免内存泄漏

在开发基于 Vue3 的大屏数据可视化系统时,ECharts 是我们最常使用的图表库之一。然而,若不注意其生命周期管理,很容易出现 图表无法响应窗口缩放、重复加载卡顿、甚至内存泄漏 等问题。

本文将结合一个真实的灌区信息化系统代码片段(index.vue),深入讲解如何在 Vue3 中 正确使用 showLoadingresizedispose ,并配合 onMountedonBeforeUnmount 生命周期钩子,构建健壮、高性能的 ECharts 图表组件。


一、背景:一个典型的大屏页面结构

在你的 index.vue 中,页面包含多个 ECharts 图表区域:

  • 雨情监测(rainChartBox
  • 水情监测(waterChartBox
  • 水量分析(amountChartBox

每个图表都需要:

  1. 初始化
  2. 加载数据前显示 loading
  3. 响应浏览器窗口大小变化
  4. 组件销毁时释放资源

为此,代码中定义了一个 chart 对象来统一管理实例:

复制代码
const chart = {
  rainChart: null,
  waterChart: null,
  amountChart: null
}

二、关键方法解析

1. showLoading():优雅地展示加载状态

作用:在异步请求数据期间,显示"加载中"提示,提升用户体验。

用法示例(以水情图为例)

复制代码
if (!chart.waterChart) {
  chart.waterChart = markRaw(echarts.init(document.getElementById('waterChartBox')))
}
chart.waterChart.showLoading({
  text: '加载中...',
  color: '#0b8ee6',
  textColor: '#fff',
  maskColor: 'rgba(0, 0, 0, 0.3)',
  zlevel: 0
});

最佳实践

  • 在发起 API 请求之前 调用 showLoading
  • 使用 markRaw 包裹 ECharts 实例,避免 Vue 响应式系统追踪(提升性能)
  • 自定义 loading 样式,匹配 UI 风格

⚠️ 注意:即使接口失败或无数据,也必须调用 hideLoading(),否则 loading 会一直显示!


2. resize():响应窗口尺寸变化

大屏系统常需全屏展示,用户可能拖动浏览器窗口或切换分辨率。若不处理,图表会变形或留白。

解决方案 :监听 window.resize 事件,批量调用所有图表的 resize()

复制代码
const handleResize = () => {
  Object.keys(chart).forEach(key => {
    chart[key] && chart[key].resize();
  });
};

onMounted(() => {
  window.addEventListener('resize', handleResize);
});

onBeforeUnmount(() => {
  window.removeEventListener('resize', handleResize);
});

关键点

  • 只在 onMounted 中添加监听器
  • 必须在 onBeforeUnmount 中移除监听器,防止内存泄漏
  • 使用 Object.values(chart).forEach(...) 批量处理,避免重复代码

3. dispose():释放资源,防止内存泄漏

ECharts 实例会占用 DOM 和内存。如果组件被销毁(如路由切换),但未调用 dispose(),会导致:

  • 内存持续增长(尤其在 SPA 中频繁切换页面)
  • 控制台报错(尝试操作已销毁的 DOM)

正确做法

复制代码
onBeforeUnmount(() => {
  // 关闭视频播放器(如有)
  if (DHVideoPlayerRef1.value) {
    DHVideoPlayerRef1.value.close();
  }
  // 清理所有 ECharts 实例
  Object.values(chart).forEach(instance => {
    if (instance) {
      instance.dispose();
    }
  });
  // 移除 resize 监听
  window.removeEventListener('resize', handleResize);
});

为什么重要?

  • dispose() 会清除内部定时器、事件绑定和 canvas 上下文
  • 避免"Cannot read property 'getAttribute' of null"等错误
  • 是专业前端工程化的体现

三、完整生命周期流程图


四、常见误区与避坑指南

误区 正确做法
每次更新数据都 new echarts.init() 复用已有实例,仅调用 setOption
忘记 hideLoading .then.catch 中都调用 hideLoading
setup() 中直接操作 DOM 确保 DOM 已挂载(放在 onMountednextTick 中)
不清理 resize 监听 导致多次绑定,resize 触发 N 次

五、总结

在 Vue3 + ECharts 的大屏项目中,资源管理和生命周期控制至关重要。通过:

  • 合理使用 showLoading / hideLoading 提升体验
  • 监听 resize 并调用 resize() 保证响应式
  • onBeforeUnmountdispose() 实例并移除监听
相关推荐
酒鼎16 分钟前
学习笔记(12-02)事件循环 - 实战案例 —⭐
前端·javascript
Bigger21 分钟前
第一章:我是如何剖析 Claude Code 整体架构与启动流程的
前端·aigc·claude
竹林81827 分钟前
从“连接失败”到丝滑登录:我用 ethers.js v6 搞定 MetaMask 钱包连接的全过程
前端·javascript
oi..31 分钟前
《Web 安全入门|XSS 漏洞原理、CSP 策略与 HttpOnly 防护实践》
前端·网络·测试工具·安全·web安全·xss
UXbot41 分钟前
2026年AI全链路产品开发工具对比:5款从创意到上线一站式平台深度解析
前端·ui·kotlin·软件构建·swift·原型模式
计算机学姐1 小时前
基于SpringBoot的高校竞赛管理系统
java·spring boot·后端·spring·信息可视化·tomcat·mybatis
CodeCraft Studio1 小时前
高性能图表库SciChart助力机器人实现实时AI驱动的性能提升
人工智能·信息可视化·机器人·数据可视化·scichart·高性能图表库·wpf图表库
一拳不是超人1 小时前
前端工程师也要懂的服务器部署知识:从 Nginx 到 CI/CD
服务器·前端
AlkaidSTART1 小时前
TanStack Query 技术指南:异步状态管理核心实践
前端·react.js
种花家的强总1 小时前
前端项目开发/维护中降低成本的方式之一:降低耦合度
前端