Nuxt/Vue项目使用Chart.js报错:禁止在mutation外修改Vuex状态
问题修复方案
核心错误(图表消失+vuex报错)原因及修复
报错Error: [vuex] do not mutate vuex store state outside mutation handlers.的根本原因是:
- Chart.js渲染过程中会直接修改传入的
data对象,而你直接将Vuex中存储的chartData传给了bar-chart组件,Chart.js的修改相当于直接修改Vuex state,触发了Vuex的严格模式校验,修改后的state被破坏导致图表消失。
修复方式:
给传给bar-chart的data做深拷贝,避免直接修改Vuex原始数据:
<bar-chart :data="cloneChartData" :options="chartOptions"/>
// 页面computed中新增 computed: { ...mapState(['chartData', 'showModal']), days() { return this.chartSelection == '0' ? '7' : '14' }, cloneChartData() { // 深拷贝,避免原始vuex数据被Chart.js修改 return structuredClone(this.chartData) // 低版本浏览器可以用JSON.parse(JSON.stringify(this.chartData))或者lodash的cloneDeep } }
下拉选择不触发图表更新修复
你存在两个问题:
- 封装的
bar-chart组件只在mounted时渲染一次,没有监听props变化更新图表 - 下拉事件绑定写法不规范,且没有正确关联逻辑
第一步:修改bar-chart组件,支持数据更新时重绘
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) }, // 新增监听数据变化 watch: { data: { handler() { // 先销毁旧实例再重绘,避免冲突 this.$data._chart?.destroy() this.renderChart(this.data, this.options) }, deep: true }, options: { handler() { this.$data._chart?.destroy() this.renderChart(this.data, this.options) }, deep: true } } }) }
第二步:修改下拉事件绑定
把:oninput替换为Vue的标准事件绑定@change:
<select v-model="chartSelection" @change="refreshChart"> <option value="0">7 days</option> <option value="1">14 days</option> </select>
模态框关闭后刷新数据修复
监听showModal状态,当模态框从开启变为关闭时触发数据刷新:
// 页面新增watch watch: { showModal(newVal, oldVal) { // 模态框关闭时刷新数据 if (oldVal === true && newVal === false) { this.refreshChart() } } }
其他语法错误修正
- 你原代码
getData中的datasets写法缺失data键,修正:
const chartData = { labels: data.data.dates, datasets: [ {backgroundColor: 'red', label: 'A', data: data.data.a}, {backgroundColor: 'blue', label: 'B', data: data.data.b}, ] }
- 你原代码
export default结构错误,computed需要放在导出对象内部,去掉多余的闭合大括号和逗号。
内容的提问来源于stack exchange,提问作者IVR
相关产品推荐
相关产品推荐

