Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

What Is Vuex? A Beginner's Guide To Vue's Application Data Store

DZone's Guide to

What Is Vuex? A Beginner's Guide To Vue's Application Data Store

In order to answer this question, we take you down the wonderful rabbit hole of Flux and explain how Flux works and applies to Vuex and Vue.js.

· Web Dev Zone
Free Resource

Learn how to build modern digital experience apps with Crafter CMS. Download this eBook now. Brought to you in partnership with Crafter Software

Vuex. Is it pronounced “vewks,” or “veweks”? Or maybe it’s meant to be “vew,” pronounced with a French-style silent “x”?

My trouble with understanding Vuex only began with the name.

Being an eager Vue developer I’d heard enough about Vuex to suspect that it must be an important part of the Vue ecosystem, even if I didn’t know what it actually was.

I eventually had enough of wondering, so I went to the documentation with plans of a brief skim through; just enough to get the idea.

To my chagrin, I was greeted with unfamiliar terms like “state management pattern,” “global singleton,” and “source of truth.” These terms may make sense to anyone already familiar with the concept, but for me, they didn’t gel at all.

The one thing I did get, though, was that Vuex had something to do with Flux and Redux. I didn’t know what those were either, but I figured it may help if I investigated them first.

After a bit of research and persistence, the concepts behind the jargon finally started to materialize in my mind. I was getting it. I went back to the Vuex documentation and it finally hit me…Vuex is freaking awesome!

I’m still not quite sure how to pronounce it, but Vuex has become an essential piece in my Vue.js toolbelt. I think it’s totally worth your time to check it out too, so I’ve written this primer on Vuex to give you the background that I wish I’d had.

Note: this article was originally posted here on Vue.js Developers on 2017/05/15.

Understanding the Problem That Vuex Solves

To understand Vuex it’s much easier if you first understand the problem that it’s designed to solve.

Imagine you’ve developed a multi-user chat app. The interface has a user list, private chat windows, an inbox with chat history, and a notification bar to inform users of unread messages from other users they aren’t currently viewing.

Millions of users are chatting to millions of other users through your app on a daily basis. However, there are complaints about an annoying problem: the notification bar will occasionally give false notifications. A user will be notified of a new unread message, but when they check to see what it is it’s just a message they’ve already seen.

What I’ve described is a real scenario that the Facebook developers had with their chat system a few years back. The process of solving this inspired their developers to create an application architecture they named “Flux.” Flux forms the basis of Vuex, Redux, and other similar libraries.

Flux

Facebook developers struggled with the “zombie notification” bug for some time. They eventually realized that its persistent nature was more than a simple bug; it pointed to some underlying flaw in the architecture of the app.

The flaw is most easily understood in the abstract: when you have multiple components in an application that share data, the complexity of their interconnections will increase to a point where the state of the data is no longer predictable or understandable. Consequentially the app becomes impossible to extend or maintain.

The idea of Flux was to create a set of guiding principles that describe a scalable frontend architecture that sufficiently mitigates this flaw. Not just for a chat app, but in any complex UI app with components and shared data state.

Flux is a pattern, not a library.

You can’t go to GitHub and download Flux. It’s a design pattern like MVC. Libraries like Vuex and Redux implement the Flux pattern the same way that other frameworks implement the MVC pattern.

In fact, Vuex doesn’t implement all of Flux, just a subset. Don’t worry about that just now though, let’s instead focus on understanding the key principles that it does observe.

Principle #1: Single Source of Truth

Components may have local data that only they need to know about. For example, the position of the scroll bar in the user list component is probably of no interest to other components.

But any data that is to be shared between components, i.e. application data, needs to be kept in a single place, separate from the components that use it. This single location is called the “store.” Components must read application data from this location and not keep their own copy to prevent conflict or disagreement.

// Instantiate our Vuex store
const store = new Vuex.Store({

  // "State" is the application data your components
  // will subscribe to

  state: {     
    myValue: 0   
  }
});
// Components access state from their computed properties
const MyComponent = {   
  template: `<div>{{ myValue }}</div>`,
  computed: {
    myValue () {
      return store.state.myValue;
    }   
  } 
};

Principle #2: Data Is Read-Only

Components can freely read data from the store. But they cannot change data in the store, at least not directly.

Instead, they must inform the store of their intent to change the data and the store will be responsible for making those changes via a set of defined functions called “mutations.”

Why this approach? If we centralize the data-altering logic than we don’t have to look far if there are inconsistencies in the state. We’re minimizing the possibility that some random component (possibly in a third-party module) has changed the data in an unexpected fashion.

const store = new Vuex.Store({ 
  state: { 
    myValue: 0
  }, 
  mutations: { 
    increment (state, value) { 
      state.myValue += value;
    }
  } 
});
// Need to update a value?
// Wrong! Don't directly change a store value.
store.myValue += 10;
// Right! Call the appropriate mutation.
store.commit('increment', 10);

Principle #3: Mutations Are Synchronous

It’s much easier to debug data inconsistencies in an app that implements the above two principles in its architecture. You could log commits and observe how the state changes in response (which you can indeed do when using Vuex with Vue Devtools).

But this ability would be undermined if our mutations were applied asynchronously. We’d know the order our commits came in, but we would not know the order in which our components committed them.

Synchronous mutations ensure that state is not dependent on the sequence and timing of unpredictable events.

Finally: What Is Vuex?

With all that background out of the way, we are finally able to address this question. Vuex is a library that helps you implement the Flux architecture in your Vue app. By enforcing the principles described above, Vuex keeps your application data in a transparent and predictable state even when that data is being shared across multiple components.

Its implementation includes a store, custom mutators, and it will reactively update any components that are reading data from the store.

It also allows for cool development features like hot module reloading (updating modules in a running application) and time travel debugging (stepping back through mutations to trace bugs).

Sound Cool. I Have Some Questions…

Maybe you’re wondering now whether or not your app needs Vuex, how it integrates with vue-devtools, or how you can commit data from asynchronous functions. My goal in this article was just to give you a primer on Vuex. I hope you’ll find if you go to the documentation now, you’ll feel well equipped to get these answers yourself.

Get the latest Vue.js articles, tutorials and cool projects in your inbox with the Vue.js Developers Newsletter.

Crafter is a modern CMS platform for building modern websites and content-rich digital experiences. Download this eBook now. Brought to you in partnership with Crafter Software.

Topics:
vuejs ,redux ,front end ,web dev ,flux

Published at DZone with permission of Anthony Gore, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}