Recently I began expunging mutations from the Vue application I work on as the way we were using them served no purpose and simply cluttered the application with pointless boilerplate, and tests for that boilerplate.
After doing this and planning on writing an opinionated post about how mutations are pointless and hinted as obsolete by Vue's creator Evan You, I did a bit of research. I quickly discovered that they can be useful as an abstraction layer but are most likely not leveraged as such in most applications and probably shouldn't be anyway.
Mutations are designed mainly as a way of tracking atomic changes to the state for debugging. They are necessary due to language limitations in ES5. However, this is no longer an issue with the eventual adoption of ES6 Proxies by most modern browsers.
Mutations can be leveraged as a useful abstraction of your state layer. For example,
commit('startLoadingBlogs'); const blogs = await getBlogs(); commit('completeLoadingBlogs', blogs);
which can be useful for debugging as this gives a more immediate overview of what is happening in your application. You're most likely to find the following in your application though,
commit('setLoading', true); const blogs = await getBlogs(); commit('setLoading', false); commit('setBlogs', blogs);
which reduces this potential abstraction layer to useless boilerplate.
Mutations can also be used as a logical point to validate data before committing it to state. Preventing state corruption is very important in avoiding hard to track bugs and can easily happen when directly committing API responses or user input.
I've personally never had an issue debugging changes to application state using breakpoints and following the logical flow of the application. Also, the Vue debugger is useful in inspecting the state tree with each change but a quick overview of each change hasn't been a significant factor in resolving any issues I've encountered.
Bulletproofing your application with validation is the only good reason I can find for useful mutations. However, (arguably) this should be happening before your action ever gets to your commit. That is if your API returns an unexpected response your service layer should handle that as an error instead.
With this in mind, I'll continue designing for a future without commits by removing individual modules mutations and replacing it with a generic state mutator. And save me the trouble of,
- No longer needing to write benign tests that simply assert that state has been changed.
- No longer needing to have both actions and commits open to understanding the data flow of my application.