首页 > 解决方案 > 不要在突变处理程序之外改变 Vuex 存储状态(错误)

问题描述

所以我收到以下错误消息:

[Vuex] 不要在突变处理程序之外改变 vuex 存储状态。

根据 Vuex文档,这个错误背后的原因是因为下面的代码试图直接改变状态。

<template>
   <div v-for="item in basicInformation" :key="item.id">
     <el-col :span="12">
          <el-form-item label="First Name">
              <el-input v-model="item.firstName" />
          </el-form-item>
     </el-col>
   </div>
</template>

export default {
        computed: {
            ...mapState(['teststore']),
            basicInformation: {
                get() {
                    return this.teststore.personData.basicInformation
                },
                set(value) {
                    this.$store.commit('updateBasic', value)
                }
            }
        }
    }

我明白为什么 Vuex 会抛出该错误,因为我仍在尝试直接改变状态。因此,根据文档,针对此特定问题的解决方案是使用带有 setter 的双向计算属性(如上面的示例中所示),并且对于单个输入字段来说效果很好。但是,我有很多输入字段供用户填写。考虑以下代码:

personData: {
        basicInformation: [
            {
                firstName: '',
                surname: '',
                email: '',
                phone: '',
                street: '',
                city: '',
                position: '',
                website: '',
            }
        ],
}

为我的所有输入字段创建一个带有 setter 的双向计算属性似乎非常冗长。有没有一种简单的方法可以让我使用 Vuex,最好v-model使用一组对象来创建输入字段?

标签: vue.jsvuejs2vuex

解决方案


我会做这样的事情:

Codesandbox:https ://codesandbox.io/s/vuex-store-ibjbr

<template>
  <div>
    <div v-for="(value, key) in basicInformation" :key="key">
      <el-col :span="12">
        <el-form-item :label="keyToLabel(key)">
          <el-input :value="value" @input="onInput({ key, value: $event })" />
        </el-form-item>
      </el-col>
    </div>
  </div>
</template>

<script>
export default {
  computed: {
    ...mapState(['teststore']),
    basicInformation() {
      return this.teststore.personData.basicInformation
    },
  },
  methods: {
    onInput({ key, value }) {
      this.$store.commit('updateBasic', { key, value })
    },
    keyToLabel(key) {
      // This is only an example
      const keyToLabel = {
        firstName: 'First Name',
        // And so on...
      }
      return keyToLabel[key]
    },
  },
}

// And in your store, something like this
const store = {
  // ...
  mutations: {
    updateBasic(state, { key, value }) {
      state.teststore.basicInformation[key] = value
    },
  },
}
</script>

推荐阅读