Vue Chart.js - 数据更改时图表不更新

新手上路,请多包涵

我正在使用 Vue.js 和 Chart.js 来绘制一些图表。每次我调用函数 generateChart() 时,图表都不会自动更新。当我检查 Vue Devtools 中的数据时,它们是正确的,但图表没有反映数据。但是,当我调整窗口大小时,图表会更新。

  • 我在做什么有什么问题?
  • 每次调用 generateChart() 时如何更新图表?

我觉得这将与 objectarray 更改检测警告有关,但我不确定该怎么做。

https://codepen.io/anon/pen/bWRVKB?editors=1010

 <template>
    <el-dialog title="Chart" v-model="showGeneratedChart">
        <line-chart :chartData="dataChart"></line-chart>
    </el-dialog>
</template>

<script>
export default {
    data() {
        const self = this;
        return {
            dataChart: {
                labels: [],
                datasets: [
                    {
                        label: "label",
                        backgroundColor: "#FC2525",
                        data: [0, 1, 2, 3, 4],
                    },
                ],
            },
        };
    },
    methods: {
        generateChart() {
            this.dataChart["labels"] = [];
            this.dataChart["datasets"] = [];

            // ... compute datasets and formattedLabels

            this.dataChart["labels"] = formattedLabels;
            this.dataChart["datasets"] = datasets;
        },
    },
};
</script>

LineChart.js

 import { Line, mixins } from 'vue-chartjs'

export default Line.extend({
    mixins: [mixins.reactiveProp],
    props: ["options"],
    mounted () {
        this.renderChart(this.chartData, this.options)
    }
})

原文由 Léo Coco 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.3k
2 个回答

为图表数据使用计算属性。而不是在手表上调用 this.renderChart 将其包装在一个方法中并在 mountedwatch 上重用该方法。

 Vue.component("line-chart", {
  extends: VueChartJs.Line,
  props: ["data", "options"],
  mounted() {
    this.renderLineChart();
  },
  computed: {
    chartData: function() {
      return this.data;
    }
  },
  methods: {
    renderLineChart: function() {
    this.renderChart(
      {
        labels: [
          "January",
          "February",
          "March",
          "April",
          "May",
          "June",
          "July"
        ],
        datasets: [
          {
            label: "Data One",
            backgroundColor: "#f87979",
            data: this.chartData
          }
        ]
      },
      { responsive: true, maintainAspectRatio: false }
    );
    }
  },
  watch: {
    data: function() {
      this._chart.destroy();
      //this.renderChart(this.data, this.options);
      this.renderLineChart();
    }
  }
});

var vm = new Vue({
  el: ".app",
  data: {
    message: "Hello World",
    dataChart: [10, 39, 10, 40, 39, 0, 0],
    test: [4, 4, 4, 4, 4, 4]
  },
  methods: {
    changeData: function() {
      this.dataChart = [6, 6, 3, 5, 5, 6];
    }
  }
});
 <!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Vue.jS Chart</title>
</head>
<body>
<div class="app">
    {{ dataChart }}
   <button v-on:click="changeData">Change data</button>
  <line-chart :data="dataChart" :options="{responsive: true, maintainAspectRatio: false}"></line-chart>

</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.6/vue.min.js"></script>
<script src="https://unpkg.com/vue-chartjs@2.5.7-rc3/dist/vue-chartjs.full.min.js"></script>
</body>
</html>

您还可以将选项设置为计算属性,如果选项不会发生太大变化,您可以设置默认道具。 https://v2.vuejs.org/v2/guide/components.html#Prop-Validation

这是一个工作的codepen https://codepen.io/azs06/pen/KmqyaN?editors=1010

原文由 azs06 发布,翻译遵循 CC BY-SA 4.0 许可协议

我的解决方案是不使用 mixins 并使用监视道具。

 watch: {
    chartData: function() {
        this.renderChart(this.chartData, this.options);
    }
  }

但是,这在我更改另一个组件中的 chartData 之前不起作用,如下所示:

 this.chartData = {
            labels: [],
            datasets: []
};
this.chartData.labels = labels;
this.chartData.datasets = datasets;

如果我只是替换标签和数据集,手表就不会触发。

原文由 Óscar García 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题