1

I know that I am supposed to use mutations to change state. However I was wondering if it is theoretivally possible to use state in a v-model binding.

My current solution:

html:

...
<input v-model='todo'>
...

with mutation:

...
 computed: {
            todo: {
                get () { return this.$store.state.todos.todo },
                set (value) { this.$store.commit('updateTodo', value) }
            }
        }
...

without mutation

...
 computed: {
            todo: {
                get () { return this.$store.state.todos.todo },
                set (value) { this.$store.state.todos.todo = value }
            }
        }
...

what I would like:

...
<input v-model='this.$store.state.todos.todo'>
...
Chris
  • 13,100
  • 23
  • 79
  • 162

1 Answers1

2

You can directly bind a Vuex state property to a component or input via v-model:

<input v-model='$store.state.todos.todo'>

But this is strongly recommended against. Vuex will warn you that you are mutating the state outside of a mutation function.

Since, when using Vuex, your state object is your source of truth which is designed to only be updated in a mutation function, it will quickly become hard to debug why the global state is changing if one component is affecting the global state without calling a mutation.

Most people, I believe, would recommend using your computed todo property example with mutations for the scenario you're describing.

thanksd
  • 54,176
  • 22
  • 157
  • 150
  • This would generate too much boilerplate code that would have to be repeated again and again throughout the application, making it harder to maintain. Isn't there an easy way to setup two-way data binding and still using mutations? – vsp May 17 '18 at 14:12
  • @vsp From the docs: ["The only way to actually change state in a Vuex store is by committing a mutation"](https://vuex.vuejs.org/en/mutations.html). So, for two-way binding a vuex state property with a v-model, the computed property with the commit in the setter is the cleanest, most succinct option. But, in my experience, it's not too often that you would so tightly couple global state to an input like this. Also, if you just need to access the data without necessarily changing it, you can use the [mapState helper function](https://vuex.vuejs.org/en/state.html) – thanksd May 17 '18 at 15:25
  • 1
    All I am saying is there should be an easy shortcut to setup two-way binding using mutations, e.g. v-model.state="todos.todo" or something like this. This would require that the mutation function for each state path can be deduced, either from annotation or by convention. – vsp May 26 '18 at 20:52
  • @vsp something like that would be nice, but currently `v-model` doesn't support anything like that. You could potentially make a custom directive to do something similar, but the question was asking specifically about using `v-model`. – thanksd May 27 '18 at 04:49