Reputation: 2059
I have a store with several state parameters and some (not all!) should be reset to their initial values.
I wonder if I can have one mutation to change several keys in vuex or is it a bad practice?
So it would look like that:
const store = new Vuex.Store({
state: {
a: 0,
b: 2,
c: 1,
z: 0
},
mutations: {
RESETALL: (state) => {
state.a = 0;
state.b = 2;
...
state.z = 0;
},
Upvotes: 0
Views: 658
Reputation: 8123
The short answer is Yes. You can, and should, change multiple state parameters in a single mutation.
What do I mean by that last point? Instead of an action that does this:
async loadData() {
commit("setLoading", true);
commit("setData", []);
commit("setError", "");
const newData = await axios.get("/data");
commit("setData", newData);
commit("setLoading", false);
}
You could have an action that expresses what it's doing and why:
async loadData() {
commit("loadingData");
const newData = await axios.get("/data");
commit("applyNewlyLoadedData", newData);
}
The mutations then look like:
loadingData = (state) => {
state.loading = true;
state.data = [];
state.error = "";
},
applyNewlyLoadedData = (state, payload) => {
state.data = payload;
state.loading = false;
},
This leads to simpler actions (which I typically see grow into complex beasts), and slightly more complex mutations (which typically do very little and make the mutation layer much more useless than it need be).
Upvotes: 3
Reputation: 76
Mutation have the access to the whole state object, you can mutate(init, set, clear) the whole state if you want..
Upvotes: -1
Reputation: 46602
You could make an init, set, clear etc, for example:
import Vue from 'vue'
/**
* State for thing
*
* Usage: this.$store.state.thing.*
*/
const defaultState = {
someDefaultProp: true,
foo: null,
bar: null
}
export const state = () => ({
...defaultState
})
/**
* Mutations / Setters
*
* Usage: this.$store.commit('thing/<method name>', payload)
*/
export const mutations = {
/**
* Initialize/hydrate state
*
* Usage: this.$store.commit('thing/init', {id: 123})
*
* @param {Object} state
* @param {Object} data
*/
init (state, data) {
// hydrate passed vars
for (const i in data) {
Vue.set(state, i, data[i])
}
},
/**
* Set single state item
*
* Usage: this.$store.commit('thing/set', {key: 'id', value: 123})
*
* @param {*} state
* @param {*} param1
*/
set (state, {
key,
value
}) {
Vue.set(state, key, value)
},
/**
* Clear state, set to null
* @param {*} state
*/
clear (state) {
// set all to null
for (const i of Object.keys(state)) {
state[i] = typeof defaultState[i] === 'undefined' ? null : defaultState[i]
}
}
}
Then use like:
this.$store.commit('thing/init', {foo: 123, bar:'baz'})
this.$store.commit('thing/set', {key: 'bar', value: 'boo'})
this.$store.commit('thing/clear')
Upvotes: 1