我已经搜索了导致这个错误消息出现的原因,但在我的代码中无法真正理解它。我使用nuext .js与Vuex。我只是不知道我在哪里修改存储而不发生突变。有人能告诉我我做错了什么吗?当我从日期选择器组件中选择某个日期时,出现此错误消息。这个解决方案的工作原理,这只是错误信息,让我,我真的不想解决它通过关闭严格模式的商店。
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>
存储是这样定义的:
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])
}
}
}
我通过在computed
选项的get()
上使用Lodash的cloneDeep
方法来解决此问题。我确实有深度复制的状态,这样它可以防止实际对象的任何突变,因此可以由set()
以同样的方式修改。
唯一需要的东西是
import { cloneDeep } from 'lodash-es'
export default {
[...]
chartData: {
get () {
return cloneDeep(this.$store.state.beta_trend.chartData)
},
[...]
},
PS:同样值得一提的是,不建议使用JSON.parse(JSON.stringify(object))
: https://flaviocopes.com/how-to-clone-javascript-object/#wrong-solutions