state

Read the value of the store field through this.$store.state

const Counter = {
  template: `<div>{{ count }}</div>`.computed: {
    count () {
      return this.$store.state.count
    }
  }
}

Copy the code

MapState helper function

When a component needs to fetch multiple states, it can be repetitive and redundant to declare all those states as computed properties. To solve this problem, we can use the mapState helper function to help us generate the calculated properties, so that you can press the key fewer times. Note that you can use alias mapping

// In the separately built version, the auxiliary function is vuex.mapstate
import { mapState } from 'vuex'

export default {
  // ...
  computed: mapState({
    // Arrow functions make code more concise
    count: state= > state.count,

    // Pass the string argument 'count' equal to 'state => state.count'
    countAlias: 'count'.// In order to be able to use 'this' to get local state, you must use regular functions
    countPlusLocalState (state) {
      return state.count + this.localCount
    }
  })
}
Copy the code

We can also pass mapState an array of strings when the name of the computed property of the map is the same as the name of the child node of State.

computed: mapState([
  // Map this.count to store.state.count
  'count'
])
Copy the code

You can also use the object expansion operator to blend this object into an external object

 localComputed () { / *... * / },
  ...mapState({
    // ...
  })
Copy the code

Using Vuex does not mean that you need to put all the states into Vuex. While putting all the state in Vuex makes state changes more explicit and easier to debug, it also makes the code tedious and unintuitive. If there are states that belong strictly to a single component, it is best to treat them as local states of the component.

getter

  • Vuex allows us to define “getters” (you can think of them as computed properties of the store) in the store. The return value of a getter is cached based on its dependency and is recalculated only if its dependency value changes. The Getter accepts state as its first argument
  • Getters are exposed as store.getters objects, and you can access these values as properties
  • Getters can also accept other getters as second arguments:
    getters: {
      doneTodosCount: (state, getters) = > {
        return getters.doneTodos.length
      }
    }
    Copy the code

MapGetters helper function

The mapGetters helper function simply maps the getters in the store to local computed properties, much like mapState, and can use alias mapping

import { mapGetters } from 'vuex'

export default {
  // ...
  computed: {
  // Mix getters into a computed object using the object expansion operator. mapGetters(['doneTodosCount'.'anotherGetter'.// ...
    ])
    
     / / the ` enclosing doneCount ` mapping for ` enclosing $store. Getters. DoneTodosCount `
     doneCount: 'doneTodosCount'}}Copy the code

Mutation

The only way to change the state in Vuex’s store is to commit mutation. Mutations in Vuex are very similar to events: each mutation has a string event type (type) and a callback function (handler). This callback is where we actually make the state change, and it accepts state as the first argument. You cannot call a mutation handler directly, only store.mit (‘increment’)

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment (state) {
      // Change the state
      state.count++
    }
  }
})

store.commit('increment') // Increment is equivalent to triggering the event
Copy the code

Payload submission

You can pass an extra parameter to store.mit, the payload of the mutation, which is equivalent to triggering the event increment and is easier to understand as an event

mutations: {
  increment (state, n) {
    state.count += n
  }
}
store.commit('increment'.10)
Copy the code
Object style submission
store.commit({
  type: 'increment', amount: 10}) // When using an object-style commit, the entire object is passed as a payload to the mutation functionCopy the code

MapMutations auxiliary function

You can use this. codeStore.mit (‘ XXX ‘) to commit mutation in the component, or use the mapMutations helper function to map methods in the component to a store.mit call (requiring store injection at the root node). Note that alias mappings can be used, as in mapGetters

import { mapMutations } from 'vuex'
export default {
  methods: {
    ...mapMutations([
      'increment'.// Map 'this.increment()' to 'this.store.com MIT ('increment')'
      // 'mapMutations' also supports payloads:
      'incrementBy' // Map 'this.incrementBy(amount)' to 'this. codestore.com MIT ('incrementBy', amount)'
    ]),
    ...mapMutations({
      add: 'increment' // Map 'this.add()' to 'this.store.mit ('increment')'}}})Copy the code

Action

  • Actions are similar to mutation, except that they commit mutation rather than directly changing the state. Actions can contain any asynchronous operation.
  • The Action function accepts a context object with the same methods and properties as the store instance, so you can submit a mutation by calling context.mit. Or get state and getters via context.state and context.getters.
const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')}}})Copy the code
Distribution of the Action

Action is triggered by the store.dispatch method

store.dispatch('increment')
Copy the code
Distribute the Action in the component

Much like mutation you use this.$store.dispatch(‘ XXX ‘) to distribute actions in the component, Or use the mapActions helper function to map a component’s methods to a store.dispatch call (requiring store injection at the root node first)

MapActions helper function

And mapState mapGetters mapMutations effect, convenient batch combined action

Module

Vuex allows us to split the Store into modules. Each Module has its own state, mutation, action, getter, and even nested submodules. This is equivalent to creating isolated store instances.

const moduleA = {
  state: {... },mutations: {... },actions: {... },getters: {... }}const moduleB = {
  state: {... },mutations: {... },actions: {... }}const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

store.state.a // -> moduleA status
store.state.b // -> moduleB status

Copy the code

Precautions ⚠️

  • Submitting mutation is the only way to change the state, and the process is synchronous.
  • Initialize all required properties in your store in advance, or you will not be able to respond
  • Auxiliary functions can all use aliases
  • Dispatch returns a Promise and can call multiple actions in succession
  • Application-level state should be centralized into a single Store object.
  • Asynchronous logic should be wrapped in actions.