2

I have a state variable in store Vuex like this:

let state = {
    order: {
        payment_method: 'Credit card',
    }
};

export default state;

Then, my template:

<select id="payment_method" class="w-full form-control form-select"
        v-model="order.payment_method">
    <option value="Credit Card">Credit Card</option>
    <option value="COD">COD</option>
</select>

When I change my select option, my state order will be updated. However, should I do that, because when I read the Vuex store principle, it said I shouldn't update the state value directly? Is that the way I am doing in the above code?

If I shouldn't do that, how will I get the value from the selection option?

user3118789
  • 589
  • 2
  • 12
  • 26
  • You update the VueX store states using mutations. For that, you can either manually invoke an action/mutation using a method in your component, or use [`mapMutations`](https://vuex.vuejs.org/guide/mutations.html#committing-mutations-in-components) or [`mapActions`](https://vuex.vuejs.org/guide/actions.html#dispatching-actions-in-components) to do that. – Terry Feb 19 '20 at 10:26
  • 1
    Does this answer your question? [2 way data binding with Vuex](https://stackoverflow.com/questions/44913187/2-way-data-binding-with-vuex) – jual ahmed Feb 19 '20 at 10:27
  • @user3118789 I added a quick example how you could use a computed property together with Vuex Mutations and Vuex Getters to safely work with the Vuex State. Let me know if that helps you. – turbopasi Feb 19 '20 at 10:48

1 Answers1

4

Exactly you shouldn't manipulate your vuex state directly. You can use Vuex Actions , Vuex Mutations and Vuex Getters to work with the state. Also in your component you could use computed Properties to get/set Vuex State data safely.

Use a computed property

In your template you could use a computed property and specificially define get and set methods for to wrap the store logic within.

<select v-model="paymentMethod">
    <option value="Credit Card">Credit Card</option>
    <option value="COD">COD</option>
</select>

{
  computed : {
    paymentMethod : {
      get() { return this.$store.getters.orderPaymentMethod },
      set(value) { return this.$store.commit('SET_ORDER_PAYMENT_METHOD', value)
    }
}

And then use this computed property as v-model for your selection v-model="paymentMethod"

Adding Mutations and Getters to your store

export const SET_ORDER_PAYMENT_METHOD = 'SET_ORDER_PAYMENT_METHOD'
const store = new Vuex.Store({
  state: {
    order: {
      payment_method: 'Credit Card'
    }
  },
  mutations : {
    [SET_ORDER_PAYMENT_METHOD] (state, method) {
       /* optional value validation here */
       state.order.payment_method = method;
    }
  },
  getters: {
    orderPaymentMethod: state => {
      /* optional filtering or else, ... */
      return state.order.payment_method
    }
  }
})
  1. Read more about Mutations here https://vuex.vuejs.org/guide/mutations.html
  2. Read more about Getters here https://vuex.vuejs.org/guide/getters.html
turbopasi
  • 3,327
  • 2
  • 16
  • 43
  • Thank you, Can I use watch instead of: https://gist.github.com/phuclh/2ca2a7e729db4784b55a1418c99d1ddc – user3118789 Feb 19 '20 at 13:55
  • 1
    shouldn't be a problem just make sure you implement the mutation correctly using your object instead of just a string like in my example. – turbopasi Feb 19 '20 at 14:07