首页 > 解决方案 > 带有对象数组的表单处理 Vuex

问题描述

我必须更新一个包含对象数组的 vuex 存储,例如:

我的用户有一个组合框可供选择,当它选择一个组合框时,它会更新数据库中该对象的属性

但是每次我在自动完成(这里的组合框)中选择一个项目时,我都会收到[vuex] do not mutate vuex store state outside mutation handlers.错误消息。所以我想知道 vuex 是否允许它,或者我是否必须改变我这样做的方式。

我正在使用 Nuxt,API 使用 express 和 mongodb 数据库

我的 Vuex :

状态:

export default () => ({
  kivaferkoi: {
    picked: [],
    notYetPicked: []
  }
})

突变:

export default {
  fillKivaferkoi (state, data) {
    state.kivaferkoi = data
  },

  editPicked (state, data) {
    state.kivaferkoi.picked = data
  }
}

行动:

import axios from 'axios'

export default {
  fetch (context, token) {
    return new Promise((resolve, reject) => {
      axios.get(process.env.api_url + '/kivaferkoi', {
        headers: {
          authorization: token
        }
      })
        .then((response) => {
          context.commit('fillKivaferkoi', response.data)
          resolve(response)
        }).catch((e) => {
        // eslint-disable-next-line no-console
          console.error(e)
          reject(e)
        })
    })
  },

  update (context, data) {
    const token = data.token
    delete data.token

    return new Promise((resolve, reject) => {
      axios.put(process.env.api_url + '/kivaferkoi/', data.value, {
        headers: {
          authorization: token
        }
      })
        .then((response) => {
          context.commit('editPicked', response.data)
          resolve(response)
        }).catch((e) => {
        // eslint-disable-next-line no-console
          console.error(e)
          reject(e)
        })
    })
  }
}

和我的 Vue 组件:

<template>
  <v-container>
    <v-row class="d-flex justify-center ">
      <v-col cols="3">
        <v-card
          color="secondary"
          rounded="lg"
          flat
        >
          <v-card-title>
            Picked one
          </v-card-title>
          <v-card-text>
            <v-list color="secondary">
              <template v-for="(item, i) in picked">
                <v-list-item :key="i">
                  <v-list-item-avatar>
                    <v-img class="avatar" :src="item.avatar ? item.avatar : avatar" />
                  </v-list-item-avatar>
                  <v-list-item-content>
                    <v-list-item-title>
                      {{ item.name }}
                    </v-list-item-title>
                    <v-list-item-subtitle>
                      {{ item.surname }}
                    </v-list-item-subtitle>
                  </v-list-item-content>
                </v-list-item>
                <v-autocomplete
                  :key="'combobox' + i"
                  v-model="item.pickedSummary"
                  :items="prositSummary"
                  flat
                  solo
                  background-color="background"
                />
              </template>
            </v-list>
          </v-card-text>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: 'Kivaferoi',
  computed: {
    picked: {
      get () {
        return this.$store.state.kivaferkoi.kivaferkoi.picked
      },

      set (value) {
        this.$store.dispatch('kivaferkoi/update', { token: this.$auth.getToken('local', value) })
      }
    }
  }
}
</script>

标签: javascriptvue.jsvuex

解决方案


尝试用副本替换分配中的数据(例如,传播,如下所示)。在 JS 中分配为链接的对象(以及数组),因此当您在任何地方更改选取的数组时,您也会在存储中对其进行变异。

fillKivaferkoi (state, data) {
    state.kivaferkoi = {...data}
  },

  editPicked (state, data) {
    state.kivaferkoi.picked = [...data]
  }

推荐阅读