[Vue警告]:监视程序中的表达式“ chartData”可能有一个无限的更新循环

时间:2018-07-29 20:56:11

标签: vue.js chart.js vue-chartjs

下面是警告中提到的观察者的我的vue文件的副本:

<script>
  import { Radar } from 'vue-chartjs'

  export default {
    extends: Radar,
    props:['chartData','options'],
    mounted () {
      this.renderChart(this.chartData, this.options)
    },
    watch: {
      chartData: {
        handler: function(newVal, oldVal) {
          this.$data._chart.update()
        },
        deep: true
      }
    }
  }
</script>

我看不到代码有什么问题,也不知道为什么会导致循环。任何帮助,将不胜感激。我通过道具传递chartData。如果您还有其他需要,请告诉我。

为使事情变得简单,下面是我传递prop chartData的方式:

<caChampions :chartData="dataForLChampions" :options="optionsForLChampions" />

每次有人从下拉列表中选择内容时,此数据都会更新。下拉菜单中的代码如下:

<v-autocomplete
                label="Champion"
                placeholder="Enter Champion's Name Here"
                :loading="championSelectLoading"
                v-model="selectedChampion"
                @input="getChampionInfo()"
                :items="champions"
                autocomplete
                autofocus
                outline
                full-width
                ></v-autocomplete>

第一次有人选择东西时,效果很好。但是,第二个选择会创建一个循环,我不确定为什么。

2 个答案:

答案 0 :(得分:1)

您应该使用reactiveProp混合而不是自己更新图表。

document中,它说:

  

在数据更改时,如果仅内部数据,它将调用update()   如果添加了新数据集,则数据集已更改或renderChart()。

<script>
  import { Radar, mixins } from 'vue-chartjs'

  export default {
    extends: Radar,
    props:['chartData','options'],
    mixins: [mixins.reactiveProp],
    mounted () {
      this.renderChart(this.chartData, this.options)
    }
  }
</script>

答案 1 :(得分:0)

ChartJS 每次调用 update() 或第一次渲染时都会改变数据对象。它将 _meta 属性添加到 chartData.dataset 并且因为您使用 deep 观察器,Vue 在 ChartJS 添加/更新 _meta 后立即调用观察器,从而导致无限更新循环。

正如@ittus 所指出的,解决方案是使用包附带的内置 mixin。它有一个限制,您必须替换整个 chartData 对象才能响应。否则必须在数据对象改变后手动调用update(),因为在内部,mixin提供的watcher不是deep

但是,如果您没有使用 vue-chartjs 库并构建了自己的包装器,或者您坚持使用 deep 观察器,则可以对 data 对象进行深度克隆.您可以使用来自 Lodash 的 JSON.parse(JSON.stringify(data))cloneDeep

进一步阅读: