1. Specific composition diagram of VUEX

2. The use of vuex

2.1 create a store. Js

When using the Vue CLI generated project, you will be asked to select Store. After selecting store, you will be given a store.js on the page. This is the original store, with the following structure:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {

  },
  mutations: {

  },
  actions: {

  }
})
Copy the code

2.2 the state

At the heart of Vuex is the store. This store instance is injected into all child components. The state property in the store holds our state.

export default new Vuex.Store({
  state: {
    count: 10}})Copy the code

Other components that want to get count need to get it using computed properties

export default {
  data(){},computed: {
    count() {
      return this.$store.state.count; }}}Copy the code

Register the store option for the root instance. The store instance is injected into all the children of the root component that are accessible through this.$store. By evaluating attributes, we can use template syntax to call count from within the template, as follows:

<template>
  <div>
    <p>{{ count }}</p>
  </div>
</template>
Copy the code

2.3 the getter

A getter is a common extracted part of a state. When the state is filtered, we can use the getter to return it to the component. For example, we define a list array in the state section:

export default new Vuex.Store({
  state: {
    list: [1.2.3.4.5.6.7.8]}});Copy the code

We want to filter out even numbers in the array and then use them in the component, so the filtering can be done in the getter.

export default new Vuex.Store({
  state: {
    list: [1.2.3.4.5.6.7.8]},getters: { // This is mainly for state processing, equivalent to the state processing method of the public part management
    modifyArr(state) { // Generalize the getter
      return state.list.filter((item, index, arr) = > {
        return item % 2= =0; })},getLength(state, getter) { // Pass the getter inside the method and call modifyArr to calculate the length
      returngetter.modifyArr.length; }});Copy the code

Then call the getter on the computed object of another component to get the desired state. The first way to use the getter is:

computed: { list() { return this.$store.getters.modifyArr; }},Copy the code

The second way to use getters is:

His $store. Getters. NameCopy the code

mapGetters

The mapGetters helper function simply maps the getters in the store to local computed properties. When we want to introduce multiple getters into a component, we can use mapGetter:

import {mapGetters} from 'vuex';
Copy the code

For example, modifyArr, getLength as defined above. We want to introduce these two and get their values:

computed: { ... mapGetter(['modifyArr'.'getLength'])}Copy the code

You can, of course, give it an alias, not necessarily the name defined by getters in the store:

computed: {
  mapGetter({
    arr: 'modifyArr'.// Map 'this.arr' to 'this.$store.getters.modifyArr', same as below
    length: 'getLength'})}Copy the code

If your computed property contains other methods, you have to use the expansion operator, which is a little different from mapState. If you write other computed properties in the mapGetter, you will get an error saying that there is no getter, so write them like this:

computed: {
  msg() {
    return this.num * 10;
  },
  ...mapGetters([
    'modifyArr'.'getLength'])}Copy the code

Or specify an alias

computed: { 
  msg() {
    return this.num * 10;
  },
  ...mapGetters({
    getList: 'modifyArr'.length: 'getLength'})}Copy the code

Copy the code and call it from the template:

<template>
  <div>
    <h2>Demonstration of mapGetters usage</h2>
    <p>Your number: {{MSG}}</p>
    <p>Your array length is: {{length}}</p>
    <ul>
      <li v-for="(item, index) in getList" :key="index">{{ item }}</li>
    </ul>
  </div>
</template>
Copy the code

2.4 mutation

When we need to change the state in store, we do not change them directly in the component, but change them through mutation, which is convenient to track the state change. For example, if we have a count variable in state, we click the plus or minus button to control its value:

mutations: {
  add(state) {
    state.count++;
  },
  reduce(state){ state.count--; }},Copy the code

In the other components, we trigger changes by defining methods and binding events, using commit:

methods: {
  add() {
    this.$store.commit('add');
  },
  reduce() {
    this.$store.commit('reduce'); }}Copy the code

2.5 the action

Action is similar to mutation, except that:

  1. The Action commits mutation rather than a direct state change.
  2. Actions can contain any asynchronous operation. Mutation can only contain synchronous transactions, so you need Action to handle asynchronous transactions. The Action controls the asynchrony process, and then calls the methods in mutation to change the state.

Here I’ll post the code directly to make it clear. First, I define a state product:

state: {
  product: 'car'
}
Copy the code

Then define a method in mutation:

changeProduct(state, payload) {
  state.product = payload.change;
}
Copy the code

Defined in action:

actions: {
  changeProduct(context, payload) { // This context is an object with the same methods and attributes as the Store instance
    // call the changeProduct method of mutation
    // context.commit('changeProduct', {change: 'ship'});
    // Change the asynchronous mode
    // setTimeout(() => {
    // context.commit('changeProduct', {change: 'ship'});
    // }, 1500)
    // Load
    let temp = 'ship+' + payload.extraInfo; 
    setTimeout(() = > {
      context.commit('changeProduct', {change: temp});
    }, 1500)}}Copy the code

Define event trigger distribution in component Methods:

methods: {
  selectProduct() {
    // this.$store.dispatch('changeProduct')
    // Load distribution
    // this.$store.dispatch('changeProduct', {
    // extraInfo: 'sportcar'
    // })
    // Or this
    this.$store.dispatch({
      type: 'changeProduct'.extraInfo: '->sportcar'})}},Copy the code