Should we use v-model to modify Vuex store?
Solution 1
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) } } }
Solution 2
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.
Solution 3
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>
Solution 4
My Solution to this was to use a getter to set value
and @input
to call the mutation.
<input
type="text"
:value="$store.getters.apartmentStreet"
@input="value => $store.commit('apartmentValue', { handle: 'street', value })"
>
getters.js:
export default {
apartmentStreet: state => state.apartment.street,
};
mutations.js
export default {
apartmentValue(state, payload) {
let oldValue = state.apartment[payload.handle];
let newValue = payload.value;
if (newValue !== oldValue) state.apartment[payload.handle] = payload.value;
}
};
If you use this method be sure to check which event you want.
Solution 5
I use this solution.
data() {
return {
formData: {
username: '',
email: '',
bio: {
firstName: '',
lastName: ''
},
games: ['civ4', 'caesar3', 'homeworld', 'cataclysm'],
}
}
},
computed: {
...mapGetters({ //or mapState
user: 'users'
})
},
watch: {
user(newValue) {
this.formData.username = newValue.name;
this.formData.email = newValue.email;
this.formData.bio.firstName = newValue.bio.firstName;
this.formData.bio.lastName = newValue.bio.lastName;
this.formData.games = newValue.games.map(x=> { return x });
}
},
beforeCreate: fucntion() {
this.$store.dispatch('getUser');
}
And then you just regularly use v-model. It is important to make deep copy of object from store, like using map for array, and how i did stuff with object inside.
And, also you need to have initiated this user object in store also, with empty fields.
Krzysztof Kaczyński
Updated on July 09, 2022Comments
-
Krzysztof Kaczyński almost 2 years
Hello I am beginner in Vue and I do have a problem that's really bugging me. I am wondering should we use v-model directive to modify vuex store? Vuex says that we should modify vuex store only by mutations but v-model makes everything easier and shorter.(I am asking because i couldn't find clear answer)
-
Krzysztof Kaczyński about 5 yearsyes, but why we shouldn't use v-model (because we should modify vuex store only by mutations) but what v-model is doing that it is not recommended to modify vuex store by v-model directive?
-
Tristan De Oliveira about 5 years<< The benefit of this convention is we can record all state mutations happening to the store and implement advanced debugging helpers such as mutation logs, snapshots, and history re-rolls / time travel. >> : vuejs.org/v2/guide/state-management.html
-
Kwesi Smart over 4 yearsI guess you mean
<input v-model="tab">
on line 2 -
Eggon about 4 years@TristanDeoliveira What if someone doesn't care about the "advanced debugging helpers", because he's building a simple app? Will v-modelling store directly cause any other problems? When I started learning Vue I did use v-models to link store directly (I used getters though not state object) and I don't remember having any problems. Isn't the best practice an overkill for small apps?
-
Jan Veselý over 3 yearsWould this work for more complex data in the message?
-
Mirko about 3 years@Eggon agreed, vuex should handle this behind the scenes...
-
Christian Johansen over 2 yearsThx for the solution. I Modified it to use dispatch("SomeAction") rather than commit. Since using an action is the recommended way to do it.