Vuex was inspired largely by Flux but also takes inspiration from the Elm Architecture. The heart of a Vuex integration is the Vuex Store:

The Vuex Store is made complete with 4 objects - state, mutations, actions, and getters.

State is simply an object that contains the properties that need to be shared within the application:

This state object only has a numbers array.

Mutations are functions responsible in directly mutating store state. In Vuex, mutations always have access to state as the first argument. In addition, Actions may or may not pass in a payload as the second argument:

In Flux architectures, mutation functions are often characterized in capital letters to distinguish them from other functions and for tooling/linting purposes. Above we have an ADD_NUMBER mutation that expects a payload and pushes that payload to the state.numbers array.

Actions exist to call mutations. Actions are also responsible in performing any or all asynchronous calls prior to committing to mutations. Actions have access to a context object that provides access to state (with context.state ), to getters (with context.getters ), and to the commit function (with context.commit ).

Here’s an example of an action that simply directly commits to a mutation while passing in the expected payload:

Getters are to a Vuex store what computed properties are to a Vue component. Getters are primarily used to perform some calculation/manipulation to store state before having that information accessible to components.

Like mutations, getters have access to state as the first argument. Here’s a getter called getNumbers that simply returns the state.numbers array:

For such a simple implementation like this, a Vuex store may not really be necessary. The examples above were provided to show the direct difference in implementation between using Vuex and a simple global store.

When a Vuex store is prepared, it’s made available to a Vue application by declaring the store object within the Vue instance.

With a well built Vuex store, components often do one of two things. They either:

GET state information (by accessing store state or getters) or DISPATCH actions.

Here’s a NumberDisplay component that directly displays the state.numbers array by mapping the getNumbers store getter on to the components getNumbers computed property.

A NumberSubmit component can hold the responsibility to allow the user to add numbers to state.numbers by mapping an addNumber component method to the store action of the same name:

Here’s the above Vuex example in CodeSandbox:

We can see that Vuex extends the simple store method by introducing explicitly defined actions, mutations, and getters. This is where the initial boilerplate as well as the main advantage comes in to using Vuex. In addition, Vuex integrates with the vue-devtools to provide time-travel debugging.

Here’s a quick gif on how the vue-devtools helps us observe store information as mutations occur, as well as being able to time-travel the UI to the moment a particular mutation has occured.

Note: The app in the gif above is the TodoMVC example implementation.

Vuex isn’t the only Flux-like library that can be used with Vue. For example, community supported libraries like redux-vue or vuejs-redux exist to help bind Vue components with a Redux store. However, since Vuex was tailored to be used only for Vue applications - it’s definitely the easiest to integrate with on to a Vue application.

#5: Vuex extends a simple store method by introducing robust steps to having our application manage state.

What’s the correct way?

Often times you may find people try to understand what the best approach is. I don’t necessarily believe there is a correct or wrong approach since each of these methods come with their advantages and disadvantages.

EventBus

- Pro: Incredibly easy to set-up.

- Con: Unable to properly track changes as they occur.

Simple Store

- Pro: Relatively easy to establish.

- Con: State and possible state changes aren’t explicitly defined.

Vuex

- Pro: The most robust way to manage application level state and integrates with Vue dev-tools.

- Con: Additional boilerplate and requires Flux-like understanding.

At the end of the day, it’s up to us to understand what’s needed in our application and what the best approach may be.

I hope this was helpful and/or made you learn something new!

All the code examples provided here can be found on Github at the awesome-fullstack-tutorials repo:

If you want to watch a slightly more detailed talk on this topic - here’s a video as well!

And finally, if you’ve never used Vue before and are potentially interested in building Vue applications, you can download the first chapter of Fullstack Vue for free!

__________________________________________________________________

👋🏾

Hi! I’m Hassan. I’m the lead author of Fullstack Vue and a Front End developer based out of Toronto, ON. I’m always trying to explain things as simple as possible, so I’ve recently started to blog more about my experiences and give talks on topics I’m passionate about.

You can always connect with me at @djirdehh.