[Vue 警告]:您可能在带有表达式 "chartData" 的观察器中有一个无限更新循环
[Vue warn]: You may have an infinite update loop in watcher with expression "chartData"
下面是我的 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>
我没有发现代码有任何问题,也不知道为什么会导致循环。任何帮助,将不胜感激。我通过道具传递图表数据。如果您还需要什么,请告诉我。
为了让事情变得更简单,下面是我如何传递 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>
有人第一次选择某样东西时,效果很好。但是,第二个选择创建了一个循环,我不确定为什么。
您应该使用 reactiveProp
mixin 而不是自己更新图表。
在document中说:
On data change, it will either call update() if only the data inside
the datasets has changed or renderChart() if new datasets were added.
<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>
ChartJS 会在您每次调用 update()
或首次渲染时改变数据对象。它将 _meta
属性 添加到 chartData.dataset
并且因为您使用 deep
观察者,Vue 在 ChartJS adding/updating _meta
之后立即调用观察者导致无限更新循环。
正如@ittus 指出的那样,解决方案是使用随包一起提供的内置 mixin。它有一个限制,您必须替换整个 chartData
对象才能反应。否则,你必须在更改数据对象后手动调用 update()
,因为在内部,mixin 提供的 watcher 不是 deep
.
但是,如果您没有使用 vue-chartjs
库并构建了自己的包装器,或者您坚持使用 deep
观察器,则可以深度克隆 data
目的。您可以使用 Lodash 中的 JSON.parse(JSON.stringify(data))
或 cloneDeep
。
进一步阅读:
下面是我的 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>
我没有发现代码有任何问题,也不知道为什么会导致循环。任何帮助,将不胜感激。我通过道具传递图表数据。如果您还需要什么,请告诉我。
为了让事情变得更简单,下面是我如何传递 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>
有人第一次选择某样东西时,效果很好。但是,第二个选择创建了一个循环,我不确定为什么。
您应该使用 reactiveProp
mixin 而不是自己更新图表。
在document中说:
On data change, it will either call update() if only the data inside the datasets has changed or renderChart() if new datasets were added.
<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>
ChartJS 会在您每次调用 update()
或首次渲染时改变数据对象。它将 _meta
属性 添加到 chartData.dataset
并且因为您使用 deep
观察者,Vue 在 ChartJS adding/updating _meta
之后立即调用观察者导致无限更新循环。
正如@ittus 指出的那样,解决方案是使用随包一起提供的内置 mixin。它有一个限制,您必须替换整个 chartData
对象才能反应。否则,你必须在更改数据对象后手动调用 update()
,因为在内部,mixin 提供的 watcher 不是 deep
.
但是,如果您没有使用 vue-chartjs
库并构建了自己的包装器,或者您坚持使用 deep
观察器,则可以深度克隆 data
目的。您可以使用 Lodash 中的 JSON.parse(JSON.stringify(data))
或 cloneDeep
。
进一步阅读: