You need to enable JavaScript to run this app. Vue 3使用Chart.js 3.5更新图表时报Maximum call stack错误如何解决
优惠活动
大模型
产品
解决方案
定价
更多

Vue 3使用Chart.js 3.5更新图表时报Maximum call stack错误如何解决

Vue 3 配合 Chart.js 3.5 调用 chart.update() 出现栈溢出错误

我使用 Chart.js 3.5 库绘制了折线图,图表渲染、响应式表现、所有动画效果均正常。尝试从父组件触发数据更新并刷新图表时,调用chart.update()抛出异常:"Uncaught (in promise) RangeError: Maximum call stack size exceeded"。

编辑补充:本地可复现该错误。

实现逻辑

  • 图表数据通过 props 从父组件传递到子组件,shouldUpdate prop 默认值为 false
  • 子组件挂载时调用 createChart 方法,使用父组件传递的数据绘制图表
  • 子组件内设置监听器监听 shouldUpdate prop 的变化
  • 点击父组件内的按钮,将 shouldUpdate 设为 true,触发子组件的监听器回调
  • 子组件修改图表数据后更新图表,再将 shouldUpdate prop 重置为 false

预期结果

  • 使用父组件传递的数据渲染图表
  • 图表按照父组件传递的配置项实现响应式和动画效果
  • 收到父组件的触发信号后图表正常更新

实际结果

  • 使用父组件传递的数据渲染图表正常
  • 图表按照父组件传递的配置项实现响应式和动画效果正常
  • 图表更新失败,抛出"Maximum call stack size exceeded"错误

父组件代码(Line.vue)

<template>
    <raw
        :type="type"
        :options="options"
        :data="chartData"
        :shouldUpdate="shouldUpdate"
        :resetUpdate="resetUpdate"
    />
    <button @click="updateData"></button>
</template>

<script>
import Raw from "./Raw.vue";

export default {
    name: "App",
    components: {
        Raw,
    },
    computed: {
        chartData: function () {
            return this.data;
        },
    },

    methods: {
        updateData() {
            this.shouldUpdate = true;
        },
        resetUpdate() {
            this.shouldUpdate = false;
        },
    },
    data() {
        return {
            type: "line",
            shouldUpdate: false,
            options: {
                responsive: true,
                animation: true,
                maintainAspectRatio: false,
            },

            data: {
                labels: ["Jan", "Feb", "Mar", "Apr", "May", "June", "July"],
                datasets: [
                    {
                        label: "My line Dataset",
                        data: [65, 59, 80, 81, 56, 55, 40],
                        fill: false,
                        borderColor: "rgb(75, 192, 192)",
                        tension: 0.1,
                    },
                    {
                        label: "My second line Dataset",
                        data: [100, 79, 8, 80, 90, 55, 60],
                        fill: false,
                        borderColor: "rgb(75, 19, 192)",
                        tension: 0.1,
                    },
                ],
            },
        };
    },
};
</script>

子组件代码(Raw.vue)

<template>
    <canvas />
</template>

<script>
import Chart from "chart.js/auto";

export default {
    name: "Raw",
    props: ["type", "data", "options", "shouldUpdate", "resetUpdate"],
    data() {
        return {
            chart: null,
            localData: null,
        };
    },
    computed: {
        parentEl: function () {
            const size = Math.min(this.$parent.width, this.$parent.height);
            return { height: size, width: size };
        },
    },
    watch: {
        shouldUpdate: function (val) {
            console.log(val);
            if (val) {
                console.log("updateTriggered");
                console.log(this.chart.data.datasets[0].data[5])
                this.chart.data.datasets[0].data[5] = Math.round(Math.random() * 100)
                console.log(this.chart.data.datasets[0].data[5])  // 检查数据是否变更
                this.chart.update(); // 该行触发错误
            }
        },

    },
    methods: {
        createChart() {
            this.localData = this.data;
            this.chart = new Chart(this.$el, {
                type: this.type,
                data: this.localData,
                options: this.options,
            });
        },

    },

    mounted() {
        this.createChart();
    },
};
</script>

<style scoped>
</style>

错误栈信息

[Vue warn]: Unhandled error during execution of watcher callback 
  at <Raw type="line" options= {} data= {labels: Array(7), datasets: Array(2)}  ... > 
  at <App> 
runtime-core.esm-bundler.js?5c40:38 [Vue warn]: Unhandled error during execution of scheduler flush. This is likely a Vue internals bug.
  at <Raw type="line" options= {} data= {labels: Array(7), datasets: Array(2)}  ... > 
  at <App> 
Uncaught (in promise) RangeError: Maximum call stack size exceeded
    at _resolveWithPrefixes (helpers.segment.js?dd3d:1797)
    at eval (helpers.segment.js?dd3d:1605)
    at _cached (helpers.segment.js?dd3d:1687)
    at Object.get (helpers.segment.js?dd3d:1604)
    at _resolveWithContext (helpers.segment.js?dd3d:1695)
    at eval (helpers.segment.js?dd3d:1647)
    at _cached (helpers.segment.js?dd3d:1687)
    at Object.get (helpers.segment.js?dd3d:1646)
    at toRaw (reactivity.esm-bundler.js?a1e9:743)
    at toRaw (reactivity.esm-bundler.js?a1e9:743)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 06:54:03