Vuex mutation inside v-for applied to an object in a list



  • Hello, I used this guide to create a store with vuex and I successfully added some properties with it: https://quasar.dev/quasar-cli/vuex-store

    But, I get this error: “Error: [vuex] do not mutate vuex store state outside mutation handlers.” when I update an object from a list of objects I have in the store.

    The error appears when I drag the slider as the model is a property of my object:

                      <q-list dark style="max-width: 400px" dense>
                        <q-item clickable v-ripple v-for="feature in features" :key="feature.id">
                          <q-item-section>
                            <q-item-label>{{feature.name}}</q-item-label>
                            <q-slider v-model="feature.value" :min="-1" :max="1" :step="0.1" snap label/>
                          </q-item-section>
                        </q-item>
                      </q-list>
    

    The object in state.js looks something like this:

        features: [
          {
            id: 0,
            name: "feature 1",
            value: 0
          },
          {
            id: 1,
            name: "feature 2",
            value: 0
          }]
    

    I do have a computed property but it doesn’t seem to help, it works fine when I only have one property.

          computed: {
            features: {
              get() {
                return this.$store.state.characterCreator.features
              },
              set(val) {
                this.$store.commit('characterCreator/updateFeatures', val)
              }
            }
          }
    

    The application works and the state does get persisted but I get that error in the console and wish to get rid of it if anyone knows how.



  • @gumball3000 that’s because you update an entire object instead a single property in the setter. Setter’s don’t play nice with objects if you use v-model and vuex. It’s a Vue thing not specifically Quasar.



  • I know it doesn’t have anything to do with Quasar, I am just asking if anyone had to do something like this before or if anyone can give me an idea on how to go about it.





  • @dobbel thanks for the link, here is how I made it work:

    I used :value and @input for the slider instead of v-model

                      <q-list dark style="max-width: 400px" dense>
                        <q-item clickable v-ripple v-for="feature in features" :key="feature.id">
                          <q-item-section>
                            <q-item-label>{{feature.name}}</q-item-label>
                            <q-slider :value="feature.value" :min="-1" :max="1" :step="0.1" snap label
                                      @change="updateFeature(feature.id, $event)"/>
                          </q-item-section>
                        </q-item>
                      </q-list>
    

    I created a function that gets triggered on @input, it takes the id of the object and the value of the slider:

            updateFeature(id, e) {
              console.log(e,id)
              let pl = {id: id, value: e}
              this.$store.commit('characterCreator/updateFeature', pl)
            }
          }
    

    Here is how my mutation looks now:

    export const updateFeature = (state, pl) => {
      console.log(pl.id, pl.value)
      state.features[pl.id].value = pl.value
    }
    


  • @gumball3000 Great! I was wondering: does the slider value still reactivity change if the features in the store are changed by for example another component?



  • I tested it and yes the slider moves to the correct position when changing the values in the store, and, of course, the sliders are still there when I navigate to another page and then go back.


Log in to reply