1. What is Vuex?
Vuex is a state management mode specially developed for Vue.js applications. It uses centralized storage to manage the common state of all components, and ensures that the state changes in a predictable manner with corresponding rules.
The dotted green line in the picture above represents the core of Vuex.
state:
The state is the data in the vue instance, which is used to store the common data of all components.
mutations:
State can only be modified through mutations, not directly modifying state data.
actions:
Actions are similar to mutations, but actions submit mutations instead of changing state directly. Asynchronous operations can be included in actions, and asynchrony is absolutely not allowed in mutations.
2. Why use Vuex?
Communication between multiple components can be very tedious, so Vuex is needed when multiple components share data.
Installation:
Use npm: import Vuex from 'vuex' Vue.use( Vuex );
Create a project:
export default new Vuex.Store({ state: { }, mutations: { }, getters: { }, actions: { } }) new Vue({ el: '#app', store, render: h => h(App) })
3. Core concepts of Vuex
1.state:
The state is the data in the vue instance, which is used to store the common data of all components.
2.getters:
I understand getters as computed attributes of all components, that is, computational attributes. The official document of vuex also says that getters can be understood as computational attributes of store s. The return values of getters are cached according to their dependencies and will be recalculated only if their dependencies change.
mapGetters Auxiliary Function:
mapGetters Auxiliary functions are simply store Medium getter Mapping to locally computed properties: import { mapGetters } from 'vuex' export default { // ... computed: { // Mixing getter s into computed objects using object expansion operators ...mapGetters([ 'doneTodosCount',// Map `this.doneTodosCount'to `this.$store.getters.doneTodosCount'.` 'anotherGetter', // ... ]) } }
This allows you to call the doneTodosCount method in the store's getters directly in the component using this.doneTodosCount
3.mutations:
I understand mutaions as methods in the store. The callback function that holds the change data in the mutations object is officially called type. The first parameter is state, and the second parameter is payload, which is a custom parameter.
Calling mutations must be submitted with store.commit()
store.commit('method', parameter)
// Support Load and Object Distribution // Distribution in Load Form store.commit('incrementAsync', { amount: 10 }) // Distribution in object form store.commit({ type: 'incrementAsync', amount: 10 })
Mutation must be a synchronous function
mapMutations Auxiliary Function:
mapMutations Auxiliary functions are simply store Medium mutations Mapping to locally computed properties: import { mapMutations } from 'vuex' export default { // ... methods: { ...mapMutations([ 'increment', // Map `this.increment()''to `this.$store.commit('increment')` // ` mapMutations `also supports loads: 'incrementBy' // Map `this.incrementBy(amount) ` to `this. $store. commit (`incrementBy', amount)` ]), ...mapMutations({ add: 'increment' // Map `this.add()''to `this.$store.commit('increment')` }) } }
4.actions:
actions are similar to mutations, except that:
- actions submit mutations instead of changing state directly
- Asynchronous operations can be included in actions, and asynchrony is absolutely not allowed in mutations
- The first parameter of the callback function in actions is context, which is an object with the same attributes and methods as the store instance.
A simple action:
const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment (state) { state.count++ } }, actions: { increment (context) { context.commit('increment') } } })
In practice, we will often use ES2015 Parametric deconstruction To simplify the code (especially when we need to call commit many times):
actions: { increment ({ commit }) { commit('increment') } }
Calling actions must trigger (distribute) with store.dispatch()
store.dispatch('method', parameter) // Support Load and Object Distribution
// Distribution in Load Form store.dispatch('incrementAsync', { amount: 10 }) // Distribution in object form store.dispatch({ type: 'incrementAsync', amount: 10 })
mapActions Auxiliary Function:
mapActions Auxiliary functions are simply store Medium actions Mapping to locally computed properties: import { mapActions } from 'vuex' export default { // ... methods: { ...mapActions([ 'increment', // Map `this.increment()'to `this.$store.dispatch('increment')` // ` mapActions `also supports loads: 'incrementBy' // Map `this.incrementBy(amount) ` to `this. $store. dispatch (`incrementBy', amount)` ]), ...mapActions({ add: 'increment' // Map `this.add()''to `this.$store.dispatch('increment')` }) } }
5.Modules:
Because of the use of a single state tree, all States of an application are concentrated on a larger object. When applications become very complex, store objects can become quite bloated. To solve these problems, Vuex allows us to split stores into modules. Each module has its own state, mutation, action, getter, and even nested sub-modules -- split the same way from top to bottom
const moduleA = { state: { ... }, mutations: { ... }, actions: { ... }, getters: { ... } } const moduleB = { state: { ... }, mutations: { ... }, actions: { ... } } const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB } }) store.state.a // -> The state of moduleA store.state.b // -> The state of moduleB