Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update Vuex store from v-model input in case of v-for

Tags:

vue.js

vuex

I've say 10 objects in an array like policies = [{name:'a',text:''},{name:'b',text:''},....]

They're iterated using v-for to show label A: Inputbox with text property binded as v-model. I want to trigger a mutation whenever a policy's text changes in v-model.

Here's the fiddle link for it. https://jsfiddle.net/dmf2crzL/41/

like image 534
Pavan Avatar asked Feb 05 '23 02:02

Pavan


2 Answers

We assume you want to use v-model for a 2-way binding along with Vuex store.

Your problem is that you want Vuex store in strict mode.

const store = new Vuex.Store({
  // ...
  strict: true
})

so all of your mutation should go through Vuex store and you can see it in Vue.js devtools.

Method 1: We can avoid the Vuex error by using the cloned object and use watcher to commit the mutation.

const store = new Vuex.Store({
  strict: true,
  state: {
    formdata: [
      { label: 'A', text: 'some text' },
      { label: 'B', text: 'some other text' },
      { label: 'C', text: ' this is a text' }
    ]
  },
  mutations: {
    updateForm: function (state, form) {
      var index = state.formdata.findIndex(d=> d.label === form.label);
      Object.assign(state.formdata[index], form);
    }
  }
});
    
new Vue({
  el: '#app',
  store: store,
  data () {
    return {
      //deep clone object
      formdata: JSON.parse(JSON.stringify(this.$store.state.formdata))
    };
  },
  computed: {
    formdata() {
      return this.$store.state.formdata
    }
  },
  watch: {
    formdata: function(form)
      this.$store.commit('updateForm', form);
    }
  }
})

Method 2: You can use computed get/set to commit your mutation as per the vuex doc

computed: {
  message: {
    get () {
      return this.$store.state.obj.message
    },
    set (value) {
      this.$store.commit('updateMessage', value)
    }
  }
}
like image 114
Kuroro Avatar answered Feb 06 '23 16:02

Kuroro


another way that I found useful:

  1. replace the v-model to a (v-on) function
  2. that function triggers a mutation
  3. the mutation ("function" in the store) change a value in state
  4. a getter ("computed" in the store) "listens" to the change in the property value and changes accordingly.

this is an example of how to filter cards with Vuex (instead of v-model:

input that triggers a function "updateFilter":

    <input type="text" placeholder="filter" v-on:input='updateFilter'>

a function (method) that triggers a mutation (commit):

  methods: {
updateFilter(event){
  this.$store.commit('updateFilter', event.target.value);
}

in the store.js, a mutation that changes data (state):

mutations: {
    updateFilter (state, filter) {
        state.filter = filter; 
    },

the state:

state: {filter: ""}

and the getter (computed) that "listens" to the change in the state.

getters: {
    filteredGames: state => {
        //your filter code here
          return filtered;
        })
    }, 

and finally, the component that needs to be filtered has this computed (getter):

  computed: {
filtered() {
  return this.$store.getters.filteredGames;
}
like image 45
L.D.R Avatar answered Feb 06 '23 15:02

L.D.R