ECharts 简介
动态数据与异步加载
掌握 setOption 的合并更新机制、loading 动画、接口数据加载和图表自适应 resize。
🎯 引言
真实项目里,数据不会写死在代码里,而是从接口获取、甚至实时刷新。学会这篇文章,你能掌握 setOption 的更新机制、加载动画、异步数据渲染和窗口自适应,让图表在真实业务里跑起来。
🧱 setOption 的合并机制
更新图表不用重新 init,再调一次 setOption 就行。默认是合并模式:新配置和旧配置合并,只有变化的部分会更新,还自带过渡动画:
// 初始渲染
chart.setOption({
xAxis: { type: 'category', data: ['周一', '周二'] },
series: [{ type: 'bar', data: [120, 200] }],
});
// 数据变化后,只传要更新的部分
chart.setOption({
series: [{ data: [150, 260] }],
});
合并模式下,新数据是“覆盖合并”而不是清空。如果新数据比旧数据短(比如从 7 天变成 3 天),多余的旧数据可能残留。这时可以传第二个参数
true,表示不合并、整体替换:chart.setOption(option, true);
🧱 加载动画 loading
接口请求有耗时,期间给用户一个转圈提示,体验会好很多:
chart.showLoading(); // 显示加载动画
// 数据回来后
chart.hideLoading(); // 关闭加载动画
chart.setOption({ series: [{ data: list }] });
🛠 从接口加载数据
结合 axios(不熟悉可以回顾本站的 Axios 课程),完整流程是:显示 loading → 请求 → 更新图表 → 关闭 loading:
views/SalesChart.vue
<template>
<div ref="chartRef" class="chart"></div>
</template>
<script setup>
import { onMounted, ref } from 'vue';
import * as echarts from 'echarts';
import axios from 'axios';
const chartRef = ref(null);
let chart = null;
const fetchData = async () => {
chart.showLoading();
const res = await axios.get('/api/sales/weekly');
const { days, values } = res.data;
chart.hideLoading();
chart.setOption({
xAxis: { data: days },
series: [{ data: values }],
});
};
onMounted(() => {
chart = echarts.init(chartRef.value);
// 先给空数据,让图表骨架先出来
chart.setOption({
title: { text: '一周销量' },
tooltip: { trigger: 'axis' },
xAxis: { type: 'category', data: [] },
yAxis: { type: 'value' },
series: [{ name: '销量', type: 'bar', data: [] }],
});
fetchData();
});
</script>
<style scoped>
.chart {
width: 100%;
height: 400px;
}
</style>
注意这里的套路:先给空数据让图表骨架渲染出来,接口返回后再填充,页面不会长时间空白。
需要定时刷新(比如监控大屏)时,用
setInterval 周期性调用 fetchData,记得在组件卸载时 clearInterval。🧱 窗口自适应 resize
浏览器窗口变化时,图表不会自动跟随缩放,需要监听 resize 事件手动调整:
const handleResize = () => {
chart.resize();
};
onMounted(() => {
window.addEventListener('resize', handleResize);
});
onBeforeUnmount(() => {
window.removeEventListener('resize', handleResize);
});
漏掉这一步,窗口一缩放图表就会溢出或者留白。
🧾 小节总结
- 再次调用
setOption即可更新图表,默认合并模式,只更新变化的部分。 - 新数据可能比旧数据短时,用
setOption(option, true)整体替换。 showLoading/hideLoading在请求前后包裹,提升等待体验。- 异步套路:先空数据渲染骨架 → 接口返回 → 再
setOption填充。 - 监听窗口
resize事件调用chart.resize(),组件卸载时移除监听。
❓ 知识问答
Q1:setOption 会重新初始化图表吗?
不会。它在原实例上增量更新,性能很好,频繁调用也没问题。
Q2:接口返回的数据格式和 ECharts 需要的不一样怎么办?
在拿到响应后先做一次数据转换(比如用 map 拆出 days 和 values 两个数组),再交给 setOption。
Q3:loading 动画样式能改吗?
可以,showLoading 接收一个配置对象,能改文字、颜色、遮罩。初学阶段用默认样式即可。
Q4:为什么图表在弹窗、抽屉里尺寸不对?
容器显示前后尺寸变了,但图表没有重算。在容器显示之后手动调一次 chart.resize() 即可。
🧪 小练习
模拟一个 1 秒后返回数据的接口,完成异步加载全流程:
- 先渲染一个空数据的折线图骨架。
- 用
setTimeout模拟接口,1 秒后返回 7 天数据。 - 等待期间显示 loading,数据到达后关闭并更新图表。
onMounted(() => {
const chart = echarts.init(chartRef.value);
// 请在这里编写代码
});
🎉 恭喜你已经能让图表对接真实数据了!下一篇我们把这些经验沉淀成一个可复用的 Vue3 图表组件,并学会按需引入减小打包体积。
