首页 > 解决方案 > Vue 页面中的 Chart.js 抛出错误:不要在突变处理程序之外改变 vuex 存储状态

问题描述

我有一个 Nuxt/Vue 应用程序,其页面显示图表。该页面还包含

我想实现以下目标:

我现在面临的主要问题是条形图在我关闭数据输入模式后几秒钟消失了,我可以在控制台中看到以下错误:Error: [vuex] do not mutate vuex store state outside mutation handlers..

此外,我似乎无法通过更改下拉值来触发更新,但这是我的次要问题。

由于此示例涉及外部 API,因此很难提出可重现的示例,但我的设置如下所示:

<template>
...
<select v-model="chartSelection", :oninput="refreshChart">
   <option value="0">7 days</option>
   <option value="1">14 days</option>
</select>
<bar-chart :data="chartData" :options="chartOptions"/>
<Modal v-if="showModal">
<!-- 
This is a custom component with its own modalToggle function.
It opens a form that allows you to create a new data point.
When this modal is closed, I would like to refresh the page
over which this modal appears
-->
...
</template>
...
<script>
async function getData(axios, store, period){
   const data = await axios.get(`my/endpoint/${period}`)
   const chartData = {
      labels: data.data.dates,
      datasets: [
        {backgroundColor: 'red', label: 'A', data.data.a},
        {backgroundColor: 'blue', label: 'B', data.data.b},
      ]
   }
   store.commit('saveChartData', chartData) // a simple assignment mutation in vuex
}
...
export default {
   async asyncData({$axios, store}) {
      await getData($axios, store, '7')
   },
   methods: {
      refreshChart() {
         return getData(this.$axios, this.$store, this.days)
      }
   },
   data() {
      return {
         chartSelection: '0', // this should determined how much data we fetch
      }
   }
},
computed: {
   ...mapState(['chartData', 'showModal']),
   days() {
      return this.chartSelection == '0' ? '7' : '14'
   }
}
...
</script>

如果有人对如何解决此问题有任何建议,请告诉我!

编辑:

仅供参考,该模式仅显示一个将图表数据提交给 API 的表单。上面示例中的bar-chartchart.js 插件如下所示:

import Vue from 'vue'
import Bar from 'vue-chartjs'
const registerComponent = function (name, originalComponent) {
  Vue.component(name, {
    extends: originalComponent,
    props: ['data', 'options'],
    mounted() {
      this.renderChart(this.data, this.options)
    },
  })
}

标签: javascriptvue.jschart.jsnuxt.jsvuex

解决方案


关于图表更新:

当数据点添加到模态中时,向父组件发出一个自定义事件,该事件将调用 getData。

<Modal v-if="showModal" @dataPointAdded="getData">

在模态中:

AddDataPoint(data) {
   /* Add data point */
   this.$emit("dataPointAdded");
}

要使用新数据更新图表组件 - 添加观察者:

props: ['data', 'options'],
mounted() {
  this.renderChart(this.data, this.options)
},
watch: 
{
    data() {
        this.$data._chart.update();
    },
    options() {
        this.$data._chart_update();
    }
}

请参阅此处的文档:https ://vue-chartjs.org/guide/#troubleshooting

自己的观察者


推荐阅读