You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3组件中如何将props作为Echarts的配置项数据使用

问题根本原因

  1. 数据加载时序不匹配:你父组件传入的xAxisData和seriesData大概率是异步请求获取的,子组件mounted生命周期执行initChart初始化图表时,父组件还没拿到接口返回的真实数据,此时传入的props是空数组,echarts直接渲染了空配置。
  2. 监听逻辑缺失更新步骤:你虽然给props加了深度监听,但是监听回调里只修改了本地option的属性,没有重新调用chart.setOption(this.option)通知echarts更新配置,所以后续props拿到真实值后,图表不会自动刷新。
  3. 所谓Proxy不是问题根源:Echarts本身可以正常读取Vue3 Proxy代理的数组内容,你看到的热重载生效是因为热重载触发时,父组件已经拿到了异步数据存在内存中,子组件重新初始化时props已经有值,所以初始化图表就直接渲染出了数据,和Proxy没有关系。你之前用Object.assign转Proxy数组为空,是因为Object.assign是用来处理普通对象的,数组转普通值直接用展开运算符或者Vue提供的toRaw方法即可。

修复方案

你可以直接修改代码如下:

<template>
  <!-- 用ref拿dom避免多实例id冲突 -->
  <div ref="chartRef" id="chart"></div>
</template>
<script>
// 如果需要拿Proxy原始值可以引入toRaw
// import { toRaw } from 'vue'
export default {
  data() {
    return {
      chart: null,
      option: {
        name: "demo",
        xAxis: {
          type: "category",
          data: [],
        },
        yAxis: {},
        series: [
          {
            data: [],
            type: "line",
          },
        ],
      },
    };
  },
  props: {
    xAxisData: Array,
    seriesData: Array,
  },
  methods: {
    initChart() {
      this.chart = this.$echarts.init(this.$refs.chartRef);
      this.updateChartOption();
    },
    // 抽离更新配置的方法复用
    updateChartOption() {
      if (!this.chart) return;
      // 如果你确实需要转普通数组,可以这么写
      // this.option.xAxis.data = toRaw(this.xAxisData)
      // this.option.series[0].data = toRaw(this.seriesData)
      this.option.xAxis.data = this.xAxisData;
      this.option.series[0].data = this.seriesData;
      this.chart.setOption(this.option);
    }
  },
  mounted() {
    this.initChart();
  },
  // 组件销毁时释放图表内存
  unmounted() {
    this.chart?.dispose();
  },
  watch: {
    xAxisData: {
      handler: function () {
        this.updateChartOption();
      },
      deep: true,
    },
    seriesData: {
      handler: function () {
        this.updateChartOption();
      },
      deep: true,
    },
  },
};
</script>
<style scoped>
#chart {
  height: 250px;
  width: 400px;
}
</style>

如果父组件的异步数据加载完成后才需要渲染图表,也可以给子组件加v-if判断数据存在后再渲染组件,就不需要额外处理监听逻辑。

内容的提问来源于stack exchange,提问作者Bobo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 19:45:03