vue“内部错误:递归过多”

问题描述 投票:0回答:1

我尝试将 Chart.js 作为 vue 组件嵌入到我的应用程序中。
一旦我尝试向图表数据集添加新数据,我就会收到错误:

Uncaught InternalError: too much recursion
    push reactivity.esm-bundler.js:798
    value helpers.collection.ts:138
    noTracking reactivity.esm-bundler.js:901
    push reactivity.esm-bundler.js:799
    value helpers.collection.ts:138
    noTracking reactivity.esm-bundler.js:901
    push reactivity.esm-bundler.js:799
    value helpers.collection.ts:138
    noTracking reactivity.esm-bundler.js:901
    push reactivity.esm-bundler.js:799
    value helpers.collection.ts:138
    noTracking reactivity.esm-bundler.js:901

Error Screenshot

应用程序.vue

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

export default {
    name: "Chart Demo",
    components: {
        Chart
    },
    data() {
        return {};
    }
};
</script>

<template>
    <div>
        <h1>Hello World</h1>
        <Chart></Chart>
    </div>
</template>

图表.vue

<template>
    <canvas ref="canvas"></canvas>
</template>

<script>
import { defineComponent } from "vue";
import { Chart } from "chart.js/auto";

export default defineComponent({
    data() {
        return {
            chart: null,
            chartData: {
                labels: [
                    "Januar", 
                    "Februar", 
                    "März", 
                    "April", 
                    "Mai", 
                    "Juni", 
                    "Juli", 
                    "August"
                ],
                datasets: [{
                    label: "Verkäufe",
                    data: [60, 65, 67, 65, 66, 69, 72, 70]
                }]
            }
        };
    },
    mounted() {

        console.log("mounted create")

        this.chart = new Chart(this.$refs.canvas, {
            type: "line",
            data: this.chartData
        });

        setInterval(() => {

            console.log("Add chart data")

            let d = 90
            this.chartData.labels.push(d);
            this.chartData.datasets[0].data.push(d);

        }, 3000);

    }
});
</script>

没有这部分:

setInterval(() => {

            console.log("Add chart data")

            let d = 90
            this.chartData.labels.push(d);
            this.chartData.datasets[0].data.push(d);

        }, 3000);

它工作得很好。

但我想创建一个值的历史记录,我需要在图表中添加新数据并重新渲染它。

操作图表数据并重新渲染的正确方法是什么?

最小可重现示例游乐场

javascript vue.js charts vue-component
1个回答
0
投票

这是 Chart.js 的已知问题。它修补数据数组以跟踪更改,类似于 Vue(特别是 2.x)的做法,这会干扰 Vue 反应性。除了修补或扩展内置 Chart.js 控制器之外,没有其他方法可以克服这个问题。或者提供只读密封数组,但这会阻止 Vue 反应性工作。

复制并冻结整个反应数据以禁用 Chart.js 自身的反应性是无效的。如果

data
对象引用在组件生命周期中发生变化,则需要额外处理。假设
data
是一个在父组件中发生变异的 prop,并且
chart
不是反应式的,那么它将是:

  created() {
    this.chart = null;
  },
  watch: {
    data: {
      deep: true,
      handler(newVal, oldVal) {
        if (newVal !== oldVal)
          this chart.data = newVal;

        this.chart.update();
      },
    },
  },
  mounted() {
    this.chart = new Chart(this.$refs.canvas, {
      type: 'line',
      data: toRaw(this.data),
    });
  }
© www.soinside.com 2019 - 2024. All rights reserved.