What is Vuex?
Managing state in an application full of components can be difficult. Facebook discovered this the hard way and created the Flux pattern, which is what Vuex is based upon.
Vuex is an official plugin for Vue.js which offers a centralized data store for use within your application. Vuex features a unidirectional data flow leading to simpler application design and reasoning.
Within a Vuex application, the datastore holds all shared application state. This state is altered by mutations that are performed in response to an action invoking a mutation event via the dispatcher.
Create Vue Cli project with Vuex
vue create setup-vuex
you will see something like following you need to select
Manually select features
you need to select Vuex as seen in the following image
you can leave remaining configs as default.
Once done open the project in your code editor and then you will see store connected to the main.js as shown in the following image, this setup has been created by Vue Cli itself
Setup Vuex in an existing Vue Cli project
As you can see following is a picture of another project which doesn’t have vuex installed, let’s try to install vuex in an existing project
npm install vuex --save
You gonna see vuex dependency in your package.json like following
all you need to do is create a folder STORE inside src and then create index.js file inside that STORE folder like following
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { }, mutations: { }, actions: { }, modules: { } })
and then add its entry to the main.js like following
now we are good to go & can use store & its features
Accessing Vuex from .vue components
Lets add a variable counter inside our vuex store ( state )
state: { counter: 0 }
Now let’s try to access it inside our .vue file, as you can see in the following image we had to make a computed property that will use vuex store reference via this.$store, there is a shorter way to do that as well
The shorter way to access vuex store state is by using mapState which you need to import from vuex itself as shown in the following image
Now let’s try to change the value of this counter, we would need to create mutations & actions for this to make it happen, in the following image we have created an action updateCounter() which commits a mutation SET_COUNTER() which actually updates the data inside the state,
this mutations being called via actions is the recommended way to update state in a vuex store, also this is on purpose!
mutations: { SET_COUNTER(state, value) { state.counter = value } }, actions: { updateCounter({ commit }, payload) { commit('SET_COUNTER', payload) } },
now that the mutations and the actions have been set let’s try to actually update the state using these, in the following image we have called mapActions and used them to update the _vuex state_
<template> <div> <button @click="increaseCounter()">increase counter</button> {{counter}} </div> </template> <script> import { mapState, mapActions } from 'vuex'; export default { name: 'HelloWorld', computed: { ...mapState(['counter']) }, methods: { ...mapActions(['updateCounter']), increaseCounter() { let payload = this.counter payload++ this.updateCounter(payload) } }, } </script> <style scoped> </style>
Add Modules to the Vuex
So Modules are really helpful in case your application grows big in size having lots of components and a large amount of data, for that above implementation will make your state bloated.
To help with that we need to use Vuex modules which allows us to divide our store into modules. Each module can contain its own state, mutations, actions, getters, and even nested modules as shown in the image
Let’s create a module in our application, for that we need to create a folder named modules inside our store folder
src > store > modules
let’s create a file inside this module folder as cart.module.js
// cart.module.jsconst state = { item: 0 }
const mutations = { SET_ITEM(state, value) { state.item = value } }
const actions = { updateItem({ commit }, payload) { commit(‘SET_ITEM’, payload) } }
export default { namespaced: true, state, mutations, actions }
<p>
</p>
Now we need to register this cart.module.js inside our main store instance as follows
Now that the module has been created let’s try to access it via our component
Access Vuex Module from Components
Following is the image which shows how you can access modules from your components along with code.
<template> <div> <button @click="increaseCounter()">increase counter</button> {{counter}} <div> <button @click="addToCart()">add to cart</button> {{item}} </div> </div> </template> <script> import { mapState, mapActions } from 'vuex'; export default { name: 'HelloWorld', computed: { ...mapState(['counter']), ...mapState('cart', ['item']) }, methods: { ...mapActions(['updateCounter']), ...mapActions('cart', ['updateItem']), increaseCounter() { let payload = this.counter payload++ this.updateCounter(payload) }, addToCart() { let payload = this.item payload++ this.updateItem(payload) } }, } </script>
here …mapState(‘cart’, [‘item’]) cart is the module name and item is variable defined in state, same goes with ..mapActions(‘cart’, [‘updateItem’])
Here is the git repository I am attaching for reference https://github.com/vueexcel/setupVuexWithModules