Search code examples
javascriptvue.jsvuexnuxt.js

v-model with dynamic input from computed


So I had a use case when I need to generate the dynamic form in a website. I'm using v-for to iterate on my form and v-model on computed properties, on Vue docs it is stated that using get() or set() are the way to go, but I got an error message

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

Here my code :

store.js

function dynamic() {
  return {
    ini: 12
  };
}

export const state = () => ({
  message: []
});

export const mutations = {
  setMessage(state, value) {
    console.log(value);
    state.message = value;
  },
  setDynamic(state, value) {
    let arr = [];
    for (let i = 0; i < 2; i++) {
      arr.push(dynamic());
    }
    state.message = arr;
  }
};

component.vue

<template>
  <section>
    <div v-for="(item, index) in message" :key="index">
      <input placeholder="Hallo V-Model" v-model="message[index].ini">
    </div>
  </section>
</template>

<script>
import { mapMutations } from "vuex";

export default {
  computed: {
    message: {
      get() {
        return this.$store.state.messages.message;
      },
      set(value) {
        this.$store.commit("messages/setMessage", value);
      }
    }
  },
  methods: {
    ...mapMutations({
      dynamic: "messages/setDynamic"
    })
  },

  beforeMount() {
    this.dynamic();
  }
};
</script>

More interactive one can be found here at my codesandbox do you had any idea why it throw error? and how to fix this issue?

Update

Manage to fix it with set 'strich mode' to false, but still, I don't know where I mutate the state outside of mutation. Answer still needed


Solution

  • I use vuex-maps-fields as a shortcut, they provide higher level get() and set() whitin vuejs so you can use v-model with them

    I mutated the object on messages so I need to clone it before applying new value. Here how the library does that so It wont mutate your state outside mutations https://github.com/maoberlehner/vuex-map-fields/blob/8ce9a2751be7996214c0c68c25afa2f2ef5b7446/src/index.js#L61