w3resource

State Management

Official Flux-Like Implementation

Due to the multiple pieces of state scattered across many components and the interactions between these states, Large applications tend to often grow in complexity.

Vue offers Vuex to solve this problem, this is our own Elm-inspired state management library. It integrates well with the vue-devtools, thus providing zero-setup access to time travel debugging.

Information for React Developers

If you are a developer coming from React, you may wonder how vuex compares to redux, which is the most popular Flux implementation in that ecosystem. Redux is actually view-layer agnostic, so we can easily be use it with Vue via simple bindings. Vuex is differs, because it knows it's in a Vue app. This allows Vuex to better integrate with Vue, thus offering a more intuitive API and an improved development experience.

Simple State Management from Scratch

It is often overlooked that the source of truth in Vue applications is its raw data object - any Vue instance only proxies access to it. Therefore, if we have a piece of state that should be shared by multiple instances, we can share it by identity:

const sourceOfTruth = {}

const vmA = new Vue({
  data: sourceOfTruth
})

const vmB = new Vue({
  data: sourceOfTruth
})

Now when sourceOfTruth is mutated, both vmB and vmA will update their views automatically. Subcomponents within each of these instances would equally have access via this.$root.$data. Now we have a single source of truth, but debugging the application would be a nightmare. Any piece of data could be changed by any part of our application at any time, while not leaving a trace.

To solve this problem, we adopt a store pattern:

var store = {
  debug: true,
  state: {
    message: 'Hello!'
  },
  setMessageAction (newValue) {
    if (this.debug) console.log('setMessageAction triggered with', newValue)
    this.state.message = newValue
  },
  clearMessageAction () {
    if (this.debug) console.log('clearMessageAction triggered')
    this.state.message = ''
  }
}

Notice that all the actions that mutate the store's state are put inside the store itself. This type of centralized state management will make it easier to understand what type of mutations could happen and how these mutations are triggered. Now whenever something goes wrong, we will also have a log of what happened leading up to the bug.

In addition, each instance/component can still own and manage its own private state:

var vmA = new Vue({
  data: {
    privateState: {},
    sharedState: store.state
  }
})

var vmB = new Vue({
  data: {
    privateState: {},
    sharedState: store.state
  }
})

As we continue developing the convention where the components are never allowed to directly mutate state that belongs to a store, but should rather dispatch events that notify the store to perform actions, we will eventually arrive at the Flux architecture. The benefit of this convention is that we can record all state mutations happening to the store and implement advanced debugging helpers such as snapshots, mutation logs, and history re-rolls / time travel.

Previous: Routing
Next: Server-Side Rendering



Follow us on Facebook and Twitter for latest update.