vue.jsnuxt.jsvuexdynamicform

Do not mutate vuex store state outside mutation handlers error for set state array


After writing the data to vuex state I am getting error because I am using v-model. The instance has both object and array instances. There is no error in the object state but I am getting the following error in the array part. Has anyone encountered this situation? what could be the solution

Steps:

  1. Write data to the form(firstName).
  2. Click the Set State Array button
  3. Change the data in the form(firstName).

Error: [vuex] do not mutate vuex store state outside mutation handlers.

export const state = () => ({
  formsArray: [],
  formObject: {}
});

const mutations = {
  SET_FORMSARRAY(state, payload) {
    console.log('formsArray', payload);
    state.formsArray = [...payload];
  },
  SET_FORMSOBJECT(state, payload) {
    console.log('formObject', payload);
    state.formObject = { ...payload };
  }
};

export default {
  namespaced: true,
  state,
  mutations
};
<template>
  <div class="container">
    <p>  {{forms}} </p>
    <br>
    <br>
    <div
      v-for="(form, index) in forms"
      :key="index"
      flat
      outlined
      rounded="lg"
    >
      <span>{{index+1}}. firstName</span>
      <v-text-field
        v-model="form.firstName"
        solo
      />
    </div>
    <v-btn
      elevation="2"
      class="ma-2"
      @click="setStateArray"
    >SET STATE ARRAY</v-btn>
    <br>
    <div style="margin-top:20px">
         <span>firstName</span>
      <v-text-field
        v-model="formsObject.firstName"
        solo
      />
     <span>lastName</span>
      <v-text-field
        v-model="formsObject.lastName"
        solo
      />
    <v-btn
      elevation="2"
        class="ma-2"
      @click="setStateObject"
    >SET STATE OBJECT</v-btn>
    </div>
    <br>
    <br>
      <p>State Array:  {{formsArray}} </p>
    <br>
    <br>
      <p> State Object:  {{formObject}} </p>
  </div>

</template>

<script>
import { mapMutations,mapState } from 'vuex'

export default {
    data() {
    return {
      forms: [],
      formsObject: {
        firstName: 'sad',
        lastName: 'sd'
      }
    }
  },
  created() {
    for (let i = 0; i < 2; i++) {
      const formData = {
        firstName: '',
      }
      this.forms.push(formData)
    }
  },
    computed: {
    ...mapState('form', ['formsArray','formObject']),
  },
  methods:{
    ...mapMutations('form',['SET_FORMSARRAY','SET_FORMSOBJECT']),
    setStateArray(){
       this.SET_FORMSARRAY(this.forms)
    },
    setStateObject(){
       this.SET_FORMSOBJECT(this.formsObject)
    }
  }
}
</script>

Example :https://stackblitz.com/edit/vuex-set-state-array-error


Solution

  • The difference between the test cases is that the array is actually an array of objects, while the object case is a flat object. When you're writing to the store with the spread syntax, this works fine for the object. When trying this with the array, only the array itself is being copied, but the reference to the objects inside still persists - therefor the error is being thrown. A possible solution would be to also use the spread syntax for the objects inside the array, or to use a deep-copy approach for writing into the store.