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"?
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":
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!
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
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
Access the state object and trigger a state change:
In a Vue component, you can access the store as this.$store. Now we can commit a mutation using a component method.
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".
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.
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.
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.
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.
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.
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:
What do you do if more than two components use it?
- duplicate the function.
- extract it into a shared helper and import it in multiple places.
- define
gettersin the store. (You can think of them as computed properties for stores)
First: define getters
Note that getters will receive the state as their 1st argument.
Second: property-style access getters
How do we access other getters?
Note that getters will receive other getters as the 2nd argument.
Third: method-style access
How does getters accept parameters?
Four: the mapGetters helper
How do we give a getter map a different name? use a object.
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.
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.commitwith its type.
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.
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.
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.
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
mapMutationsin methods
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.
simplify the code with argument destructuring
One: dispatching actions
Actions are triggered with the store.dispatch method:
Two: dispatching actions in components
How can we dispatching actions in components?
this.$store.dispatch('xxx')- with
mapActionsin methods