Using Vuex the right way
Vue.js is a Javascript framework for building user interfaces and single page applications. It’s becoming one of the most popular front-end frameworks, competing with React and Angular. As you may know, as an application gets bigger, you are in more need for state management solutions. Even though you can make your own or use something like Redux, Vue core team provides its own official library called Vuex for handling application state.
Vuex is a state management library provided by Vue core team and inspired by Facebook’s flux model. It’s really easy to integrate it with existing Vue applications. Also, it’s very flexible and scalable. It’s based on mutability, unlike Redux that’s all about immutability, but the concepts of using Vuex/Redux are really similar. Let’s take a look at Vuex flow:
The most basic scenario will be that from the Vue component we dispatch an action that will do some logic (ex. fetch some data) similar to the middleware in Redux, and commit the result to mutations. Mutations are like reducers if you are familiar with Redux, and this is where mutability takes its place. Mutations mutate state with a new value and that’s all they’re supposed to do. When the state is mutated it will trigger the re-rendering cycle. Vuex provides a few helper methods to make the integration of Vuex with Vue components easier. You can call mutations directly from the Vue components but it’s not recommended. It’s always a better solution to call an action that commits a mutation even if that’s all it does. This is something that’s proven to be a better option in the long run. When the application gets bigger, calling mutations directly can lead to forgetting some restrictions or not updating all necessary states. That leads us to store.subscribe or store.subscribeAction functionality. In Vuex we are able to trigger our custom handlers after certain action or mutation is called. This feature is really powerful for adding logging to your application or setting the right states when a certain mutation happens, but could lead to messy code and should be used with caution.
Vuex has modules to provide scalability and for that you have two different approaches.
You can use Vuex modules with the namespaced option set to true or false. From my experience, I wouldn’t recommend using namespaced option set to true, and I’ll explain why. When you set property namespaced true in your modules, you are forcing that all actions, mutations and getters are called with module name in front of their name. For example “auth/getToken”, auth will be the module name and getToken will be the action. This means that it will only call getToken action in the auth module. In case that we didn’t have namespaced property, we would call action only by its name “getToken”. The main difference between these two approaches is that if we have the same action name (getToken) in other modules, they will be triggered too. By not adding the namespaced property, we get really similar architecture to Redux and Flux, where all actions with the same name are triggered, and each module can then update its own state.
As you can see from the diagrams, when your application gets bigger it will be more maintainable without namespaced property. This architecture is proven to be scalable on many projects by Redux. Of course, this doesn’t mean you can’t have some modules with namespaced properties set to true, just be aware of the decisions you make and how they can impact your application. The good example of a problem with scaling namespaced application is really similar to MVC problem and it can look like this:
Usually, developers are scared to modify that code, because who knows what will happen in the application.
The last thing you should be aware of when using Vuex is that Vuex is just an instance of Vue.js. That means that Vuex is reactive and that all the states are actually in data property, and that the getters are computed properties.
Vuex source code
This ties you to the Vue framework and if you want to switch to React, for instance, it will be a lot harder. Also if you are developing for low-end devices having the reactive store can be performance heavy. You could go the immutable way by using Object.freeze, that will result in fewer observers created.
Conclusion
In the end, Vuex is an amazing tool, it has really great integration with Vue.js and it’s easy and fun to use. You can find it challenging when migrating to another framework, because it’s reactive and because it’s tightly coupled with Vue.js framework. If you can live with that, Vuex is a great choice for a state management system.