【问题标题】:Trying to reactively update chart data, however, the chart does not reflect the changes. Vue.js但是,尝试响应式更新图表数据时,图表并未反映更改。 Vue.js
【发布时间】:2019-09-19 13:28:37
【问题描述】:

遗憾的是,我又遇到了一些 Vue.js 反应性问题。目前,我的代码在mounted() 上渲染一次图表,然后每次数据更新时都会重新渲染图表,这要感谢观察者。这确实有效(除了我不确定如何删除以前渲染的图表这一事实),但是,考虑到我使用的是 Vue,我不确定这是否是进行更新的正确方法。对我来说,在数据更新时更新已经渲染的图表似乎是一个更好的选择,而不是渲染一个全新的图表并删除旧的图表。

我尝试使用this.data = the new data 更改数据,但是,我知道这不会使对象反应。我也尝试使用 this.$set ,如此处所述 - https://vuejs.org/v2/guide/reactivity.html ,但是,我没有用它实现任何目标。我可能没有正确使用它。我还尝试仅更改对象的一个​​属性,该属性也不会影响图表。

<template>
    <div id="app">
        <button @click="updateChart()">X</button>
        <canvas id="myChart"></canvas>
    </div>
</template>

<script>
export default {
    data: function() {
        return {
            data: {
                labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
                datasets: [{
                    label: '# of Votes',
                    data: [12, 19, 3, 5, 2, 3]
                }],
            }
        }
    },
    methods: {
        updateChart(){
            this.data = {
                labels: ['Red', 'Red', 'Red', 'Red', 'Red', 'Red'],
                datasets: [{
                    label: 'EYOOOOOOOOOOOOOO',
                    data: [6, 7, 8, 9, 10, 11]
                }],
            }
            /*this.$set(this.data, {
                labels: ['Red', 'Red', 'Red', 'Red', 'Red', 'Red'],
                datasets: [{
                    label: 'Please Work',
                    data: [6, 7, 8, 9, 10, 11]
                }],
            }))*/
            /*this.$set(this.data, 'labels', ['Red', 'Red', 'Red', 'Red', 'Red', 'Red'])*/
        },
        renderChart(data, options){
            var ctx = document.getElementById('myChart').getContext('2d');
            var myChart = new Chart(ctx, {
                type: 'bar',
                data: data,
                options: options
            });
        }
    },
    mounted() {
        this.renderChart(this.data, this.options)
    },
    watch: {
        data: function() {
            this.renderChart(this.data, this.options)
        }
    }
}

【问题讨论】:

  • 那么您是想让updateChart 方法工作,还是让data 的观察者工作?如果updateChart 工作正常,为什么不在updateChart 中进行更新后致电renderChart?此外,您可能需要使用{ deep: true } 作为data 的观察者:vuejs.org/v2/api/#vm-watch

标签: javascript vue.js vuejs2


【解决方案1】:

发件人:https://vuejs.org/v2/guide/reactivity.html

有时您可能希望将多个属性分配给现有的 对象,例如使用 Object.assign() 或 _.extend()。然而,新 添加到对象的属性不会触发更改。在这样的 情况下,创建一个新对象,其属性来自原始对象 对象和mixin对象:

尝试通过以下方式更新您的this.data

this.data = Object.assign({}, {
                labels: ['Red', 'Red', 'Red', 'Red', 'Red', 'Red'],
                datasets: [{
                    label: 'Please Work',
                    data: [6, 7, 8, 9, 10, 11]
                }],
            })

【讨论】:

  • 嗯,我的控制台日志显示数据已更新,但是,我的图表没有显示任何更改。有什么线索吗?
  • 您使用什么库来呈现图表?听起来问题在于renderChart
【解决方案2】:

尝试对数据使用深度观察者

{
  watch: { 
    data: {
      handler: function(value) {
        this.renderChart(this.data, this.options)
      },
      deep: true,
    }
  }
}

顺便说一句,拥有一个名为 datadata 属性令人困惑...我建议将其更改为 chartData

Vue 中,只有顶级对象属性会触发响应式更改。 deep 将导致嵌套对象(在您的情况下为 labelsdatasets)也触发更新。大多数情况下不需要深,因此要消除开销,您需要根据需要添加它。

确保在不通过Vue.set 之前不要向现有数据对象添加任何新属性。当 UI 不更新数据更改时,这是下一个最常见的问题。

【讨论】:

  • 你能简单解释一下这个深度观察者是做什么的吗?
  • 在 Vue 中,只有对象的顶级属性会触发响应性。 Deep 将导致嵌套对象(标签/数据集)也触发更新。大多数情况下不需要深度,因此要消除开销,您需要根据需要添加它。
猜你喜欢
  • 2020-12-04
  • 2015-07-28
  • 1970-01-01
  • 1970-01-01
  • 2017-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多