Search code examples
vue.jsvuex

How can I binding big data from vuex with form?


I'm trying the Vue and I've got a problem with binding data from vuex with my form. I created a simple store

export default {
  state: {
    form: {},
  },
  action: {
    async getForm({ commit }, id) {
      try {
        const response = await axios.get(`url/${id}`);
        commit('setForm', response.data);
      } catch(e) {
        console.error(e);
      }
    },
  },
  mutations: {
    setForm(state, payload) {
      state.form = payload;
    },
  },
  getters: {
    getFormFromStore = state => state.form,
  },
}

And I ceated a simple component

data() {
  return {
    form: {},
  };
},
computed: {
  ...mapGetters('form', 'getFormFromStore'),
},
methods: {
  ...mapActions('form', 'getForm'),
},
watch: {
  getFormFromStore: {
    deep: true,
    handler(newVal) {
      this.form = Object.assign({}, newVal);
    },
  },
},
async mounted() {
  await this.getForm();
},
<div>
  <v-form>
    <v-text-field v-model=form.name/>
    <v-text-field v-model=form.lastName/>
    <v-text-field v-model=form.age/>
    <v-text-field v-model=form.address.street/>
    <v-text-field v-model=form.address.house/>
    <v-text-field v-model=form.children.girl/>
    <v-text-field v-model=form.children.girl.name/>
  </v-form>
</div>

But I'm getting a problem when I try to change the form. And I don't know how to fix it. I've read some articles, but it says that I need to create the computed properties, but if I have form with 100 fields?

My error

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


Solution

  • Object.assign makes a shallow copy of state.form. Two-way binding in v-model mutates the state.

    The watcher should make a deep copy instead. If there are multiple levels of nesting, third-party utility for deep clone/merge can be used. A simple and less efficient way is to create a deep copy with JSON builtin:

      this.form = JSON.parse(JSON.stringify(newVal));