错误:[vuex] 不要在变异处理程序 vuex (nuxt.js) 之外改变 vuex 存储状态 [英] Error:[vuex] do not mutate vuex store state outside mutation handlers vuex (nuxt.js)
问题描述
我已经搜索了导致此错误消息出现的原因,但在我的代码中无法真正理解它.我正在使用 Nuxt.js 和 Vuex.我只是看不到我在哪里修改商店而不发生突变.有人可以告诉我我做错了什么吗?当我从日期选择器组件中选择某个日期时,会出现此错误消息.此解决方案按预期工作,只是错误消息让我感到困扰,我真的不想通过关闭存储的严格模式来解决它.
组件.vue
<v-col class="chart"><v-card><v-card-title>每日测试趋势</v-card-title><v-row><v-col cols=4"><b-form-group label="From"class=ml-3"><b-form-datepicker id="datepicker-from";v-model="chartDataFrom";类=mb-2"/></b-form-group></v-col><v-col cols=4"><b-form-group label="To"><b-form-datepicker id="datepicker-to";v-model="chartDataTo";类=mb-2"/></b-form-group></v-col><v-col cols=4"><b-form-group label=操作系统版本"class=mr-3"><b-form-select v-model="selectedOS";:options="OSVersions"><模板#first><b-form-select-option :value=null"禁用>-- 请选择操作系统版本 --</b-form-select-option></模板></b-form-select></b-form-group></v-col></v-row><v-骨架加载器v-if="$fetchState.pending";类=mx-自动";最大宽度=300"类型=卡片"/><p v-else-if=$fetchState.error">发生错误:(</p><div v-else><图表:数据=图表数据"/>
</v-card></v-col></模板><脚本>从'~/components/Trends/Charts/Chart'导入图表导出默认{name: 'BetaTrend',成分: {图表},异步获取(){等待 this.$store.dispatch('beta_trend/getChartData')},fetchOnServer: 假,计算:{图表数据:{得到 () {返回 this.$store.state.beta_trend.chartData},设置(数据){this.$store.commit('beta_trend/SET_CHART_DATA', 数据)}},图表数据来自:{得到 () {返回 this.$store.state.beta_trend.from},设定值) {this.$store.commit('beta_trend/SET_FROM', value)this.$fetch()}},图表数据:{得到 () {返回 this.$store.state.beta_trend.to},设定值) {this.$store.commit('beta_trend/SET_TO', value)this.$fetch()}},操作系统版本:{得到 () {返回 this.$store.state.beta_trend.os}},选定的操作系统:{得到 () {返回 this.$store.state.beta_trend.selectedOs},设定值) {this.$store.commit('beta_trend/SET_SELECTED_OS', value)this.$fetch()}}}}<样式范围></风格>
商店定义如下:
export const state = () =>({图表数据:[],来自:空,到:空,操作系统:['全部','1803','19042'],selectedOs:空})导出常量突变 = {SET_CHART_DATA(状态,数据){state.chartData = 数据},SET_FROM(状态,来自){state.from = 从},SET_TO(状态,到){state.to = 到},SET_SELECTED_OS(状态,操作系统){state.selectedOs = os}}导出常量动作 = {async getChartData ({ commit, state }) {const data = await this.$axios.$get('api/frontend/trend/XXX', {参数:{来自: state.from,到:state.to,操作系统:state.selectedOs}})提交('SET_CHART_DATA',数据)如果(state.from === null){提交('SET_FROM',数据.日期[0])}if (state.to === null) {commit('SET_TO', data.dates[data.dates.length - 1])}}}
我使用 Lodash 的 <我的 computed
选项的 get()
上的 code>cloneDeep 方法.我确实有深度复制的状态,这样它可以防止实际对象的任何突变,因此可以通过 set()
以相同的方式进行修改.
唯一需要的是
import { cloneDeep } from 'lodash-es'导出默认{[...]图表数据:{得到 () {返回 cloneDeep(this.$store.state.beta_trend.chartData)},[...]},
PS:还值得一提的是,不推荐使用 JSON.parse(JSON.stringify(object))
:https://flaviocopes.com/how-to-clone-javascript-object/#wrong-solutions
I've already searched what causes this error message to appear but could not really get my head around it in my code. I'm using Nuxt.js with Vuex. I just can't see where am i modifying the store without mutation. Can someone please tell me what am i doing wrong ? This error message appears when i pick some date from the date picker component. This solution works as intended, it's just the error message that bugs me and i dont really want to solve it by turning off the strict mode for store.
Component.vue
<template>
<v-col class="chart">
<v-card>
<v-card-title>Daily beta trend</v-card-title>
<v-row>
<v-col cols="4">
<b-form-group label="From" class="ml-3">
<b-form-datepicker id="datepicker-from" v-model="chartDataFrom" class="mb-2" />
</b-form-group>
</v-col>
<v-col cols="4">
<b-form-group label="To">
<b-form-datepicker id="datepicker-to" v-model="chartDataTo" class="mb-2" />
</b-form-group>
</v-col>
<v-col cols="4">
<b-form-group label="OS Version" class="mr-3">
<b-form-select v-model="selectedOS" :options="OSVersions">
<template #first>
<b-form-select-option :value="null" disabled>
-- Please select OS version --
</b-form-select-option>
</template>
</b-form-select>
</b-form-group>
</v-col>
</v-row>
<v-skeleton-loader
v-if="$fetchState.pending"
class="mx-auto"
max-width="300"
type="card"
/>
<p v-else-if="$fetchState.error">
An error occurred :(
</p>
<div v-else>
<Chart :data="chartData" />
</div>
</v-card>
</v-col>
</template>
<script>
import Chart from '~/components/Trends/Charts/Chart'
export default {
name: 'BetaTrend',
components: {
Chart
},
async fetch () {
await this.$store.dispatch('beta_trend/getChartData')
},
fetchOnServer: false,
computed: {
chartData: {
get () {
return this.$store.state.beta_trend.chartData
},
set (data) {
this.$store.commit('beta_trend/SET_CHART_DATA', data)
}
},
chartDataFrom: {
get () {
return this.$store.state.beta_trend.from
},
set (value) {
this.$store.commit('beta_trend/SET_FROM', value)
this.$fetch()
}
},
chartDataTo: {
get () {
return this.$store.state.beta_trend.to
},
set (value) {
this.$store.commit('beta_trend/SET_TO', value)
this.$fetch()
}
},
OSVersions: {
get () {
return this.$store.state.beta_trend.os
}
},
selectedOS: {
get () {
return this.$store.state.beta_trend.selectedOs
},
set (value) {
this.$store.commit('beta_trend/SET_SELECTED_OS', value)
this.$fetch()
}
}
}
}
</script>
<style scoped>
</style>
the store is defined like this:
export const state = () => ({
chartData: [],
from: null,
to: null,
os: [
'All',
'1803',
'19042'
],
selectedOs: null
})
export const mutations = {
SET_CHART_DATA (state, data) {
state.chartData = data
},
SET_FROM (state, from) {
state.from = from
},
SET_TO (state, to) {
state.to = to
},
SET_SELECTED_OS (state, os) {
state.selectedOs = os
}
}
export const actions = {
async getChartData ({ commit, state }) {
const data = await this.$axios.$get('api/frontend/trend/XXX', {
params: {
from: state.from,
to: state.to,
os: state.selectedOs
}
})
commit('SET_CHART_DATA', data)
if (state.from === null) {
commit('SET_FROM', data.dates[0])
}
if (state.to === null) {
commit('SET_TO', data.dates[data.dates.length - 1])
}
}
}
I fix this issue by using Lodash's cloneDeep
method on the get()
of my computed
option. I do have the state that is deep copied, this way it prevents any mutation of the actual object, and can therefore be modified by the set()
in the same way.
The only needed thing is
import { cloneDeep } from 'lodash-es'
export default {
[...]
chartData: {
get () {
return cloneDeep(this.$store.state.beta_trend.chartData)
},
[...]
},
PS: also worth mentioning that JSON.parse(JSON.stringify(object))
is not recommended: https://flaviocopes.com/how-to-clone-javascript-object/#wrong-solutions
这篇关于错误:[vuex] 不要在变异处理程序 vuex (nuxt.js) 之外改变 vuex 存储状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!