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

AlpineJS 3 搭配 Charts.js 4.4.6 调用Chart.update()触发栈溢出错误

解决AlpineJS与Chart.js v3+更新时栈溢出问题

问题原因

Chart.js v3及以上版本会对传入的数据对象进行深度响应式监听,而AlpineJS自身也有一套响应式系统。当直接将Alpine的响应式data对象传给Chart.js实例时,两者的监听机制会互相触发更新,形成无限递归,最终导致Maximum call stack size exceeded错误。而Chart.js 2.9.4及更早版本没有这种深度监听逻辑,所以不会出现冲突。

解决方案

核心思路是切断AlpineJS与Chart.js的响应式数据绑定,不让两者共享同一个数据对象:

1. 初始化Chart时传入数据副本

在init方法中,不要直接传递this.data,而是创建数据副本,避免Chart.js监听Alpine的响应式对象。

2. 更新数据时直接操作Chart实例的数据

更新时直接修改Chart实例的data属性,再调用update(),无需通过Alpine的响应式数据中转,避免触发不必要的响应式更新。

修改后的完整代码:

<div x-data="chartComponent()" class="max-w-xl mx-auto">
    <canvas id="myChart"></canvas>
    <button
        @click="updateChart"
        class="mt-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
    >
        Update Chart
    </button>
</div>

<script>
    function chartComponent() {
        return {
            chart: null,
            // Alpine本地存储数据,仅用于初始值备份
            localData: {
                labels: ['January', 'February', 'March', 'April', 'May'],
                datasets: [{
                    label: 'Sales',
                    data: [10, 20, 30, 40, 50],
                    backgroundColor: 'rgba(75, 192, 192, 0.2)',
                    borderColor: 'rgba(75, 192, 192, 1)',
                    borderWidth: 1
                }]
            },
            init() {
                const ctx = document.getElementById('myChart').getContext('2d');
                // 创建数据副本传给Chart.js,切断与Alpine响应式绑定
                const chartData = JSON.parse(JSON.stringify(this.localData));
                this.chart = new Chart(ctx, {
                    type: 'bar',
                    data: chartData,
                    options: {
                        responsive: true,
                        plugins: {
                            legend: {
                                position: 'top',
                            },
                            tooltip: {
                                callbacks: {
                                    label: function (context) {
                                        return `${context.label}: ${context.raw}`;
                                    }
                                }
                            }
                        }
                    }
                });
            },
            updateChart() {
                // 直接修改Chart实例的数据
                this.chart.data.datasets[0].data = [50, 40, 30, 20, 10];
                // 同步更新Alpine本地数据(按需选择)
                this.localData.datasets[0].data = [50, 40, 30, 20, 10];
                this.chart.update();
            }
        };
    }
</script>

补充说明

  • 如果不需要在Alpine中保留数据副本,可以直接在init里定义独立的Chart数据,完全脱离Alpine的响应式系统。
  • JSON.parse(JSON.stringify())是通用的深拷贝方式,适用于各种数据结构;如果数据结构简单,使用对象/数组展开语法做浅拷贝也能满足需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 04:01:13