State management in vue.js
Table of Contents
If you’re front-end developer and you’re using JavaScript on the daily basis then probably you’ve asked yourself a question – “What tools can be used to make the developing process easier, more clear and faster?”
Nowadays we have a big stack of technologies that would work out for you. One of the most progressive and the easiest to learn JavaScript frameworks for building user interfaces is Vue.js. It is MIT-licensed open-source project that has awesome community support.
If you wrote an application using Vue that’s a little bit bigger than small, probably you know that it’s difficult to keep track of your app’s state when it grows. There’s so much data moving around from one component to another. That’s the reason why Vuex, state management library for Vue, based on Flux pattern, appeared. Sounds cool, huh? Let’s get our hands dirty with Vuex.
Of course, using state management solutions is not always required. If your application is small and you don’t have much data flow inside then you have less need to implement it. In other case, let’s assume we have simple blog app with the following structure:
<App> => <BlogList> => <BlogItem>
Looks simple, right? If we have a need to move data from App component to BlogItem, we have to send it via BlogList first. Still looks simple? But what if we’ll add another child to BlogItem? The data should flow via 2 middle components to get to that child. It’s getting worse, right? Imagine that child having Button element. When the button is clicked, you have to notify BlogItem element that will notify BlogList and finally App. Writing this is a bit tedious, not telling about implementing it in a real project.
Right, right, you can keep local states for every component and that will work. The problem is, you will easily loose track of what exists and why a particular event is happening at a given time. It is very easy to loose data sync that ends up in a pool of confusion.
That’s where the Vuex comes into play. It will manage your application’s state. Your data flow will come from one source named “store” and you’ll be easily able to keep track of what’s happening in your app.
State
State – is the current working status of your app. It is determined by what data exists and where in the given time.
In Vuex state is the plain object:
{ blogItems: [], // etc }
Looks simple, right? Let’s add Vuex to your existing Vue.js project(how to create Vue.js project you can read here at the official documentation: https://vuejs.org/v2/guide/ ).
`import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex)
Store
Store in Vuex is an object that keeps the application’s state. Just everything about the state stored there. You can create a store instance using the following code:
const store = new Vuex.Store({ state: { blogItems: [] } })
You can pass store options as an object.The state that has been discussed previously is passed in alongside with other store members that we will discuss in following sections.
After the store has been created, there’s a need to tell Vue that this store will be used.
const App = new Vue({ el: '#app', template: '<div>Hello</div>', // here we pass store object store: store })
Accessing store state
After successful store set up and letting Vue know about it, we would like to know how we can access the store state. Vuex state is reactive, therefore it can be threatened as the usual reactive object returned from a data function. We will use computed property to retrieve the state. That’s easy-peasy:
const App = new Vue({ computed: { blogItems: function() { return this.$store.state.blogItems } }, el: '#app', template: '<li v-for="item in blogItems" :key="item.id">Show something</li>', store: store })
The computed property blogItems can then be bound to the template using interpolation.
<li v-for="item in blogItems" :key="item.id">Show something</li>
Store getters
We will violate DRY when more than one component depends on a computed value because we will have to compute for each component. So, it’s best to handle computation inside the store using the getters property(each getter has an access to state using the state variable that’s passed to its arguments by default):
const store = new Vuex.Store({ state: { blogItems: [] }, getters: { allBlogItems: state => state.blogItems } }) const App = new Vue({ computed: { blogItems: function() { return this.$store.getters.allBlogItems } }, el: '#app', template: '<li v-for="item in blogItems" :key="item.id">Show something</li>', store: store })
Mutations
Mutations are synchronous functions that are used to update state. As the first agrument, mutation receives state, the second one – is a variable that’s passed by user. Remember, this is the only proper way to update state in Vuex – MU-TA-TI-ONS. You shouldn’t even think about directly mutating state, like this:
addBlogItem(blogItem) { this.$store.state.blogItems.push(blogItem); }
The right way to do it:
const ADD_BLOG_ITEM= "ADD_BLOG_ITEM"; const store = new Vuex.Store({ state: { blogItems: [] }, … mutations: { [ADD_BLOG_ITEM] (state, blogItem) { state.blogItems.push(blogItem) }, } })
Mutations are like events. To call them, you have to use the commit
method:
const App = new Vue({ ... methods: { addBlogItem: function() { return this.$store.commit('ADD_BLOG_ITEM') } }, el: '#app', template: '<li v-for="item in blogItems" :key="item.id">Show something</li>', store: store })
Store actions
Actions – are asynchronous functions that are mainly used to fetch data from external sources. They allow you to carry out async operations and then commit mutations as soon as async operations are completed.
const ADD_BLOG_ITEM= "ADD_BLOG_ITEM"; const store = new Vuex.Store({ state: { blogItems: [] }, … mutations: { [ADD_BLOG_ITEM] (state, blogItem) { state.blogItems.push(blogItem) }, } actions: { addBlogItem: ({ dispatch, commit }, payload) => { return axios.post(url, payload) .then(function (response) { // commit mutation after request successfully finished commit(ADD_BLOG_ITEM, response.data) }) .catch(function (error) { // handle error }); } } })
To fire action within component, you have to use dispatch method:
const App = new Vue({ ... methods: { addBlogItem: function() { return this.$store.dispatch('addBlogItem') } }, el: '#app', template: '<li v-for="item in blogItems" :key="item.id">Show something</li>', store: store })
Final notes on Vue
We’ve covered basic Vuex flow in details, so have fun trying to build an amazing app using state management for Vue.js.
Read more: React Hooks – revolutionary changes in React
This may interest you:
How to get into Project Management?
Project Management Tools for Boosting Efficiency
Product Manager and Product Owner – what is the difference?
10 useful tools for project managers in 2019
5 Project Management Phases for software development
6 Popular Types of Project Management Methodologies
Project Manager vs. Scrum Master: Key Differences & Similarities
Project Manager vs Product Owner – what is the difference?
Beginner’s Guide to Scrum in Project Management
What does an Account Manager do in a software development company?