Search code examples
arraysvue.jsvuexv-model

Bind multiple form inputs to vuex store array


So I have this array in Vuex Store, and I want to bind it's fields to multiple inputs in a form. The way I manged to get this working is like this:

template:

            <b-form-input id="CustName2"
                      type="text"
                      v-model="CustName2" :maxlength="50"
                      placeholder="Nombre">
            </b-form-input>
            <b-form-input id="CustAddr"
                      type="text"
                      v-model="CustAddr" :maxlength="50"
                      placeholder="Dirección">
            </b-form-input>
            <b-form-input id="CustPostCode"
                      type="text"
                      v-model="CustPostCode" :maxlength="10"
                      placeholder="Cod. Postal">
            </b-form-input>

Computed:

 computed: {
    
    CustName2: {
        get () {
            return this.$store.state.orderproperties.CustName2
        },
        set (value) {
            this.$store.commit('SetCustName2', value)
        }
    },
    CustAddr: {
        get () {
            return this.$store.state.orderproperties.CustAddr
        },
        set (value) {
            this.$store.commit('SetCustAddr', value)
        }
    },
    CustPostCode: {
        get () {
            return this.$store.state.orderproperties.CustPostCode
        },
        set (value) {
            this.$store.commit('SetCustPostCode', value)
        }
    }
}

store.js:

orderproperties: {
      CustName2: '',
      CustAddr: '',
      CustPostCode: ''
    }

The thing is, now I need to add 5 more properties (5 more fields to the form), and I feel like I could be getting a single computed property as an array, and then bind this to each field in the form; instead of creating a single computed property for each field. The problem is that the setter will not bind each array element to each input. Any ideas on how to refactor this? Right now, for each field I need a computed property, a Store mutation and a Store getter for each field.


Solution

  • one of approaches:

    In store.js add universal mutation

    import Vue from 'vue'
    
    export const mutations = {
       updateProp: (state, payload) => {
         const { prop, value } = payload
         Vue.set(state.orderproperties, prop, value)
       },
    }
    

    in methods add

    methods {
      onChange(prop, value) {
        this.$store.commit('updateProp', {prop: prop, value: value})
      },
      getValue(prop) {
        return this.$store.state.orderproperties[prop]
      }
    }
    

    in template

    <b-form-input id="CustName2"
      type="text"
      @change="onChange('CustName2', $event)"
      :value="getValue('CustName2')"
      :maxlength="50"
      placeholder="Nombre">
    
    
       <b-form-input id="CustAddr"
         type="text"
         @change="onChange('CustAddr', $event)"
         :value="getValue('CustAddr')"
         :maxlength="50"
         placeholder="Dirección">
    
       ...