Author: Yeaseon Blog: YeaseonZhang.github. IO

This article is basically a pirated version of the official tutorial, explaining Vuex in plain English with some cuts.

If that doesn’t bother you, keep reading and hopefully it will help.

Learning a new technology requires knowing the two W’s, “What && Why”.

“What is XX?” Why (XX) should be used or what are the advantages of (XX) and finally how (XX) should be used.

What is Vuex?

Vuex is a redux-like state manager that manages all Vue component states.

Why Vuex?

When you plan to develop large single-page applications (spAs), multiple view components will depend on the same state, and behavior from different views will need to change the same state.

When this happens, you should consider using Vuex, which extracts the shared state of components and manages it as a global singleton. This way, wherever you change the state, components that use that state will be notified to do so.

Here’s how to use Vuex.

Simplest example of Vuex

This article does not cover how to install Vuex and goes directly to the code.

import Vue from 'vue';
import Vuex form 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
    state: {
        count: 0
    },
    mutations: {
        increment (state) {
            state.count++
        }
    }
})Copy the code

The above is the simplest Vuex. Every Vuex application is a store, and mutations are included in the store for the shared state of components and the method to change the state (temporarily called method).

It should be noted that the state of the store can only be changed through mutations, not store.state.count = 5; Change it directly (actually, it can be changed, but it is not recommended. Change state without mutations, and the state will not be synchronized). Trigger mutations to change state using the store.mit method:

store.commit('increment');

console.log(store.state.count)  // 1Copy the code

A simple Vuex application is achieved.

Use Vuex in Vue components

If you want the Vuex state to be updated and the corresponding Vue component to be updated, the easiest way is to get state on COMPUTED (calculated properties) in Vue

// Counter component const Counter = {template: '<div>{{count}}</div>', computed: {count () {
            returnstore.state.count; }}}Copy the code

The example above directly operates on the global state store.state.count, and each component that uses this Vuex will be imported. To address this, Vuex provides a mechanism to inject state from the root component into each child component through the Store option.

// The root component import Vue from'vue';
import Vuex form 'vuex';

Vue.use(Vuex);
const app = new Vue({
    el: '#app',
    store,
    components: {
        Counter
    },
    template: `
        <div class="app">
            <counter></counter>
        </div>
    `
})Copy the code

With this injection mechanism, the child component Counter can be accessed via this.$store:

// Counter component const Counter = {template: '<div>{{count}}</div>', computed: {count () {
            return this.$store.state.count
        }
    }
}Copy the code

MapState function

computed: {
    count () {
        return this.$store.state.count
    }
}Copy the code

If this is too repetitive, we can simplify the process by using the mapState function.

import { mapState } from 'vuex';

export default {
    computed: mapState ({
        count: state => state.count,
        countAlias: 'count'// alias' count 'is equivalent to state => state.count})}Copy the code

There are even simpler ways to use it:

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

Getters object

If we need to do a calculation on the state object, it looks like this:

computed: {
    doneTodosCount () {
        return this.$store.state.todos.filter(todo => todo.done).length
    }
}Copy the code

If multiple components are going to do this, copy the function in multiple components. This is inefficient, and when the process changes and the same changes are made across multiple components, it becomes even less maintainable.

The getters object in Vuex allows us to do centralized processing in the store. Getters accepts state as the first argument:

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: '... '.done: true },
      { id: 2, text: '... '.done: false }
    ]
  },
  getters: {
    doneTodos: state => {
      return state.todos.filter(todo => todo.done)
    }
  }
})Copy the code

Pass in Vuestore.gettersObject call.

computed: {
  doneTodos () {
    return this.$store.getters.doneTodos
  }
}Copy the code

Getters can also accept other getters as a second argument:

getters: {
  doneTodos: state => {
      return state.todos.filter(todo => todo.done)
  },
  doneTodosCount: (state, getters) => {
    return getters.doneTodos.length
  }
}Copy the code

MapGetters helper function

Similar to mapState, both simplify code. The mapGetters helper function simply maps getters in store to local computed properties:

import { mapGetters } from 'vuex'

exportdefault { // ... Computed: {// Mix getters into a computed object using the object expansion operator... mapGetters(['doneTodosCount'.'anotherGetter', / /... ] )}}Copy the code

It could also be written:

computed: mapGetters([
      'doneTodosCount'.'anotherGetter', / /... ] )Copy the code

So there are two auxiliary functions in Vue’s computed attributes:

import { mapState, mapGetters } form 'vuex';

exportdefault { // ... computed: { mapState({ ... }), mapGetter({ ... }}})Copy the code

Mutations

As mentioned earlier, the only way to change the status in Vuex’s store is mutations.

Each mutation has an event type type and a callback function handler.

Const store = new Vuex. Store ({state: {count: 1}, mutations: {increment (state) {/ / the status state. Count++}}})Copy the code

To call mutation, you need to call the mutation type with the store.mit method:

store.commit('increment')Copy the code

Payload

You can also pass a second parameter, the payload of mutation, to store.mit:

mutaion: {
    increment (state, n) {
        state.count += n;
    }
}

store.commit('increment', 10);Copy the code

We can pass in a payload object, which is a payload object.

mutation: {
    increment (state, payload) {
        state.totalPrice += payload.price + payload.count;
    }
}

store.commit({
    type: 'increment',
    price: 10,
    count: 8
})Copy the code

MapMutations function

As an exception, Mutations also has a mapping function, mapMutations, which helps us simplify the code, using the mapMutations auxiliary function to map the methods in the component to the store.mit call.

import { mapMutations } from 'vuex'

exportdefault { // ... methods: { ... mapMutations(['increment'// Map this.increment() to this.$store.commit('increment')]),... mapMutations({ add:'increment'// Map this.add() to this.$store.commit('increment')}}}Copy the code

Mutations must be a synchronization function.

Mutations aren’t enough for us if we need asynchronous operations, so we need Actions instead.

Aciton

After reading the content of the previous Vuex, you will be getting started. So let the actions learn on their own. (The actions are a bit complicated and I need some time to digest them.)

conclusion

Vuex was a blur last month, but now it’s easy to understand.

The most important thing to learn a new technology is practice. It is not enough to just watch tutorials and demos.

The road ahead is long.