-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Mutation handlers need some serious re-evaluation 🐒 #1889
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This is why we are reconsidering mutations for Vuex 5, so please wait for the RFC to give your feedback. In the meantime, you can create your own Store with composition API and avoid mutations completely. You could also take a look at Pinia Store which does not have mutations, but ultimately, Vuex 5 will bring an API that isn't as verbose as with mutations Also note that with the composition API, you can design your own |
@posva thank you for the suggestions, I'll look into this. What are the major purposes of mutation handlers anyway? Is it just debugging? What if all components just ignore mutation handlers and mutate all store properties directly, like shown in the method 1 above - will we only loose better debugging capabilities and that's it? |
Hear hear! Vuex doesn't follow the KISS principle. Too much code write for every store - .mutations, actions, getters, ..mapGetters everywhere, plus computed methods... Also getters take too much code! THIS DOESN'T WORK - From the main page.
|
What problem does this feature solve?
Hey guys, can we discuss Vuex mutation handlers - arguably the most nonsensical thing in Vuex?
I've been developing a big complex app for 2+ years with Vue and I still haven't found good reasons to keep using mutation handlers. According to Vuex docs and my experience, the only thing they do is make debugging a little bit easier in some situations, while over-complicating the codebase and making development process undoubtedly a lot more annoying for no good reason.
Examples:
Compare the 2 examples demonstrated below, look at how much less code it takes to open a dialog and to change some of its properties by using the 1st method, compared to the 2nd method.
Method 1: direct mutation
This method achieves the same thing as the 2nd method, but requires hundreds of times less code (when app has a lot of components), which in itself makes code cleaner and less susceptible to bugs, which results in much more enjoyable development experience.
App.vue
Dialogs.vue
// NO COMPUTED PROPERTIES NEEDED
store.js
I know this method might, in theory, make it more difficult to track down the source of errors, but in practice, if there's only 3-5 functions that change a specific state property, it's pretty easy to determine which one of them caused the error by following the event logic. Mutations are always caused by some sort of known event (button press, input change, etc), so when an error appears during a specific event, it's not that difficult to track down the function that caused it, without using mutation handlers anyway.
Method 2: mutation handlers
This method is considered to be "the best practice" just because it improves debugging, while requiring a ton more work. Here's all the code you will need to set up the same dialog using this method.
This example is written with the official Vuex guidelines in mind (create getters, setters, create a separate action and mutation for each property, etc) to additionally demonstrate the absurdity of the current Vuex implementation.
App.vue
Dialogs.vue
store.js
And you have to do this for every single component of the app.
Add to that the inability to mutate properties from within a Vuex action and the fact that direct mutations are 10 - 500 times faster than the mutation handlers in cases where properties is mutated rapidly (once every few milliseconds), e.g. a slider without a debouncer / throttle, and it becomes clear that this insanity needs a re-evaluation.
In the real code, I managed to reduce the amount of computed properties by generating them dynamically for every nested property in
beforeCreated
hook of every component, and reduced the amount of mutations by creating a single generalized custom mutation function that sets specified deep properties automatically from the specified'dot.notation.property.path'
string. But if this kind of heavy lifting is supposed be implemented manually by every developer for every new project, Vuex shouldn't really be considered a library then.What does the proposed API look like?
Anything but this. Surely there is a better / smarter / simpler way to do traceable mutations.
The text was updated successfully, but these errors were encountered: