You need to enable JavaScript to run this app. Vue3向Chart.js传Fetch数据时触发Maximum call stack size exceeded错误
优惠活动
大模型
产品
解决方案
定价
更多

Vue3向Chart.js传Fetch数据时触发Maximum call stack size exceeded错误

问题原因与解决方案

问题根源

这个错误是Vue3响应式代理和Chart.js内部数据处理逻辑冲突导致的:
你在子组件中直接将*响应式的props数组(chartData、chartLabels)*传递给了Chart.js的配置对象,Chart.js运行时会修改传入的数组,添加内部自定义属性,这一操作会触发Vue的响应式更新逻辑,二者的读写逻辑相互触发形成无限循环,最终导致调用栈溢出。
硬编码测试正常的原因是:同步执行的硬编码在Chart.js初始化前就完成了数组填充,后续没有数组修改操作,不会触发双方的循环调用。


解决方案

核心解决思路是:传递给Chart.js的数组必须是非响应式的普通数组,不要直接传递Vue的响应式代理对象。

1. 修改子组件初始化逻辑

在setup中创建Chart配置时,对props的数组做浅拷贝,脱离响应式代理:

// 子组件setup内的chartDetails修改为
const chartDetails = {
  labels: [...props.chartLabels], // 浅拷贝转为普通数组
  fill: true,
  datasets: [
    {
      label: "",
      data: [...props.chartData], // 浅拷贝转为普通数组
      borderColor: "rgb(24, 144, 255)",
      tension: 0.1,
      fill: true,
    },
  ],
}

2. 完善子组件监听更新逻辑

原来的监听逻辑只监听了chartLabels,且更新时没有替换Chart内部的数据源,需要调整:

// 子组件的watch修改为
watch: {
  // 同时监听两个数组变化
  chartData: {
    deep: true,
    handler: updateChart
  },
  chartLabels: {
    deep: true,
    handler: updateChart
  }
},
methods: {
  updateChart() {
    // 更新前先做浅拷贝,传递普通数组给Chart
    this.sampleChart.data.labels = [...this.chartLabels]
    this.sampleChart.data.datasets[0].data = [...this.chartData]
    this.chartRef.update(250)
  }
}

(可选)优化父组件数据赋值逻辑

避免多次push触发多次响应式更新,可一次性处理完数据再赋值:

// 父组件getTimelineData方法修改
getTimelineData: function () {
  fetch("http://localhost:8080/sample.json")
    .then((res) => res.json())
    .then((data) => {
      const labels = data.data.map(el => el.timestamp)
      const values = data.data.map(el => el.value)
      this.chartLabels = labels
      this.chartData = values
    });
},

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 11:09:01