It will make the complicated code much simplier.
I think the mutation functions have to get the commit function of store object as third argument:
mutations: {
addTotal(state, value, commit) { state.total = value; },
addTotalAndTax(state, value, commit) {
state.tax = value * 0.12;
// call another mutation, the same as this.$store.commit(...) in application
commit('addTotal', value);
}
}
in application:
// run one mutation
this.$store.commit('addTotal', 12.35);
. . .
// run both two mutations by one call
this.$store.commit('addTotalAndTax', 76.05);
Just use an action and commit two mutations
@posva Thanks, I know about this solution but I do not this that way is comfortable.
Are there some reasons to decline my proposal? From my POV it is looking logical and secure. Am I wrong?
One of the purpose of mutation is to keep trackable for each state update.
If you call a mutations in other mutations, they cannot be separated in devtools and it decrease trackability.
A mutation is meant to do one single thing. If you find yourself writing duplicated code, you can always use function to refactor that code
I woiuld also vote against this. we have actions to take care fo this.
I found out that you can commit mutation from another mutation just by calling this.commit(), This is old thread but I haven't found any recent info. Is it a bug or it was really added?
@ktsn, @LinusBorg you use react-way, no Vue-way. IMHO. In that way the most actions will be just the wrappers around mutations:
actions: {
addTotal(store, value) { // this method is not necessary, useless ballast
store.commit('addTotal', value); // just call a mutation, nothing helpful
},
addTax(store, value) { // this method is not necessary, useless ballast
store.commit('addTax', value); // just call a mutation, nothing helpful
},
addTotalAndTax(store, value) { // great! Useful action! Finally.
store.commit('addTax', value);
store.commit('addTotal', value);
}
},
mutations: {
addTotal(state, value) { state.total = value; },
addTax(state, value) { state.tax = value * 0.12; }
}
Too much useless code for.... "to keep mutations trackable"? Really? Ok, let the Vuex has the untrackableCommit() method. It will apply mutations untrackable way and do the same thing as commit(), but it will be available to call from another mutations.
With that method the code above will be like this (we do NOT need any actions at all):
mutations: {
addTotal(state, value) { state.total = value; },
addTax(state, value) { state.tax = value * 0.12; }
addTotalAndTax(state, value, untCommit) {
untCommit('addTax', value);
untCommit('addTotal', value);
}
}
Is it possible? Make a sence?
@panstromek Thank you, I hope it will work.
mutations = {
test(state) {
this.commit('test2');
}
test2(state) {
console.log('Don't you mind to learn javascript first');
}
}
@m00nk Just to clear something. Even though I wrote solution here, I would vote against using that. If you use it, you'll find out that debug tool tracks mutations in wrong, opposite order, which makes it harder to debug and nonsense to revert only one of them.
Also, your example is use of derived property, which is better to do with getters. I think about different uses this might have (like updating object references - adding Comment and updating comments array on Post object), but those I would do in one mutation so that store data is consistent after every mutation.
Another solution is to use modules without namespaces and have two mutations with same name that update module related data. I think this is useful solution for use case i described, when you have modules separated by entity. I think some others might do it in two different mutations and call them from action to have more granular mutation tracking, I guess it depends on what you want.
But what in case to call other mutation on response of Synchronous?
@inventico that way is not working in Vuex3
Surely if u want to mutate multiple values u can just do:
mutations: {
addTotalAndTax(state, {total, tax}) {
state.total = total;
state.tax = tax;
}
}
If multiple mutations need to be called at once then fine to put that in the action. An action can be used as a dumb wrapper in these exceptional cases.
Most helpful comment
Just use an action and commit two mutations