Vuex: Official English notes

322 阅读3分钟

Vuex

An English note for studying official documents. Vuex

Introduction

What is Vuex?

Zero: Definition

Definition: Vuex is a state management pattern + library for Vue.js applications. It serves as a centralized store for all the components in an application, with rules ensuring that the state can only be mutated in a predictable fashion.

Version: Vuex3, Vuex4, Vuex5(Pina)

One: state management pattern

What is a "State Management Pattern"?

image.png

It is a self-contained app with the following parts:

  • The state, the source of truth that drives our app;
  • The view, a declarative mapping of the state;
  • The actions, the possible ways the state could change in reaction to user inputs from the view.

This is a simple representation of concept of "one-way data flow":

image.png

However, the simplicity quickly breaks down when we have multiple components that share a common state:

  • Multiple views may depend on the same piece of state.
  • Actions from different views may need to mutate the same piece of state.

So, how to fix it?

  • Why don't we extract the shared state out of the components, and manage it in a global singleton? With this, our component tree becomes a big "view", and any component can access the state or trigger actions, no matter where they are in the tree!

image.png

When should i use it?

  • If your app is simple: A simple store pattern may be all you need.
  • If you are building a medium-to-large-scale SPA, Vuex will be the natural next step for you.

Installation

image.png

Getting Started

Zero: store

What is store?

  • At the center of every Vuex Application is the store. A "store" is basically a container that holds your application state.

Vuex store VS a plain global object

  • Vuex stores are reactive.
  • You cannot directly mutate the store's state. The only way to change a store's state is by explicitly committing mutations.

One: the simplest store

image.png

Access the state object and trigger a state change:

image.png

In a Vue component, you can access the store as this.$store. Now we can commit a mutation using a component method.

image.png

State

Zero: why

Why introduce state into the store?

One: single state tree

Vuex uses a single state tree - that is, this single object contains all your application level state and serves as the "single source of truth".

image.png

Two: getting vuex state into vue components

How do we display state inside the store in our Vue components?

  • Since Vuex stores are reactive, this simplest way to "retrieve" state from it is simply returning some store state from within a computed property.

image.png Whenever store.state.count changes, it will cause the computed property to re-evaluate, and trigger associated DOM updates.

Global use of store?

  • Vuex "injects" the store into all child components from the root component through Vue's plugin system, and will be available on them as this.$store.

image.png

Three: the mapState helper

When a component needs to make use of multiple store state properties or getters, how can we do?

  • To deal with this we can use of the mapState helper which generates computed getter funtions for us.

image.png

We can also pass a string array to mapState when the name of a mapped computed property is the same as a state sub tree name.

image.png

Four: object spread

Note that mapState returns an object. How do we use it in combination with other local computed properties?

  • we can make use of object spread operator.

image.png

Five: components can still have local state

If a piece of state strictly belongs to a single component, it could be just fine leaving it as local state. You should weigh the trad-offs and make decisions that fit the development needs of your app.

Getters

Zero: why

Why introduce getters into the store?

  • Sometimes we may need to compute derived state based on store state, for example filtering through a list of items and counting them:

image.png

What do you do if more than two components use it?

  1. duplicate the function.
  2. extract it into a shared helper and import it in multiple places.
  3. define getters in the store. (You can think of them as computed properties for stores)

First: define getters

image.png Note that getters will receive the state as their 1st argument.

Second: property-style access getters

image.png

How do we access other getters?

image.png Note that getters will receive other getters as the 2nd argument.

Third: method-style access

How does getters accept parameters?

image.png

image.png

Four: the mapGetters helper

image.png

How do we give a getter map a different name? use a object.

image.png

Mutations

Zero: why

Why introduce mutations into the store?

  • The only way to actually change state in a Vuex store is by committing a mutation. Vuex mutations are very similar to events.

image.png Note that the handler function reveive the state as the 1st argument.

How do we call the mutation handler?

  • You cannot directly call a mutation handler. To invoke a mutation handler, you need to call store.commit with its type.

image.png

Two: accept an additional argument

How does a mutation handler accept an additional argument?

  • You can pass an additional argument to store.commit, which is called the payload for the mutation.

image.png

In most cases, the payload should be an object so that it can contain multiple fields, and the recorded mutation will also be more descriptive.

image.png

Three: using constants for mutation types

  • Putting all constants in a single file allows your collaborators to get an at-a-glance view of what mutations are possible in the entire application.

image.png

Four: mutations must be synchronous

  • One important rule to remember is that mutation handler functions must be synchronous.

Five: committing mutations in components

How can we commit mutations in components?

  • this.$store.commit('xxx')
  • with mapMutations in methods

image.png

image.png

Note that mutations are synchronous transactions, to handle asynchronous operations with actions.

Actions

Zero: why

Why introduce actions into the store?

  • Instead of mutating the state, actions commit mutations.
  • Actions can contain arbitrary asynchronous operations.

image.png

simplify the code with argument destructuring

image.png

One: dispatching actions

Actions are triggered with the store.dispatch method:

image.png

image.png

Two: dispatching actions in components

How can we dispatching actions in components?

  • this.$store.dispatch('xxx')
  • with mapActions in methods

Three: composing actions

image.png