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
相关产品推荐
相关产品推荐

