Should we use v-model to modify Vuex store?
https://vuex.vuejs.org/guide/forms.html
When using Vuex in strict mode, it could be a bit tricky to use
v-model
on a piece of state that belongs to Vuex.The "Vuex way" to deal with it is binding the
<input>
's value and call an action on the input or change event.
Be sure to check out the simple "Two-way Computed Property" example on that page:
<input v-model="message">computed: { message: { get () { return this.$store.state.obj.message }, set (value) { this.$store.commit('updateMessage', value) } }}
I think another good option which hasn't been mentioned in any answer here is to use vuex-map-fields. In fact, the library author has written a very nice explanation for the library's usefulness. As per its GitHub page, to use the library you can do something like this:
In your Vuex Store, you can have a snippet similar to this:
import Vue from 'vue';import Vuex from 'vuex';import { getField, updateField } from 'vuex-map-fields';Vue.use(Vuex);export default new Vuex.Store({ // ... modules: { fooModule: { namespaced: true, state: { foo: '', }, getters: { getField, }, mutations: { updateField, }, }, },});
And in your component code, you can have something along the lines of this:
<template> <div id="app"> <input v-model="foo"> </div></template><script>import { mapFields } from 'vuex-map-fields';export default { computed: { // `fooModule` is the name of the Vuex module. ...mapFields('fooModule', ['foo']), },};</script>
Additional examples for various use cases are shown in the library's GitHub repository that I linked to in the first sentence of this answer.
Above solution can also implemented with mutations:
<template> <input v-model="message"></template><script>import { mapMutations, mapState } from 'vuex';export default { computed: { ...mapState({messageFromStore: 'message'}), message: { get() { return this.messageFromStore; }, set(value) { this.updateMessage(value); } } }, methods: { ...mapMutations('updateMessage') }};</script>