Why do I do this collection of essays? There are tons of vuex tutorials out there, and it’s even been packaged by some of the gods; On the one hand, I want to introduce you to use VUex from the simplest and most basic place. On the other hand, I also want to review VUex. Ok, without further ado, let’s briefly introduce vuex.

The first step, if you want to learn about a technology, is to go to its website, and you’re right. When you go to the website, you’ll see “What is Vuex?” :

As shown in the figure, it is a state management mode within an application. It is a small repository that centrally stores the state of all components and keeps our stored state changing in a predictable way. As for the prediction, NOW I will not do more explanation, I believe that after reading this article, you will have their own understanding.

Step one, understand Vuex

๐Ÿคฏ Imagine a scenario

If your project has many pages (components/views) with multiple levels of nesting between them, two problems arise when these pages share a state:

  • Multiple views depend on the same state
  • Actions from different views need to change the same state

๐Ÿคช Use your little head and you will come up with a solution to the above methods:

  • For the first problem, if it is a multilevel nested relationship, you can solve it by using parent-child component parameter passing. It is a bit troublesome, but fortunately it can be solved. For sibling components or components with more complex relationships, this is difficult, and although there are various ways to solve it, it is really not elegant, and as the project gets bigger, the code will become a mountain of shit, which is annoying.
  • For the second problem, you can reference directly through parent-child components, or change or synchronize multiple copies of state through events. This pattern is fragile and often makes the code difficult to maintain, as well as making the code a mess.

๐Ÿ˜‡ At this point, now that I have thought about this, how about another way of thinking:

  • Extract the same state that each component needs to depend on and manage it globally using the singleton pattern.
  • In this mode, any component can access the state directly, or all components are updated when the state changes.

๐Ÿ‘ถ That’s when Vuex was born!

This is the basic idea behind Vuex, borrowed from Flux and Redux. Unlike other patterns, Vuex is a state management library designed specifically for Vue to leverage the fine-grained data response mechanism of VUe.js for efficient state updates.

๐Ÿ˜จ Next, you’ll see the vuex life cycle chart below:

๐Ÿคฉ When should vuex be used?

  • This varies from person to person. If you don’t need to develop a large, single-page app, you don’t need to use Vuex at all. If you only have two or three pages, you don’t need to use Vuex to add more files than you currently have.
  • If your project reaches the size of a mid-to-large application, you’ll probably be thinking about how to better manage state outside of components, and Vuex will be a natural choice.

๐Ÿค” that’s all for a brief introduction to vuex. Let’s use it together!

Step 2: Install

Enter the project, enter the installation instruction on the command line, and press Enter

npm install vuex --save

Then configure vuex to work by creating a store folder under the SRC path and creating an index.js file with the following contents:

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

Vue.use(Vuex);

const store = new Vuex.Store({
    state: {
        // Define a name for global use
        name: 'Joe'.// Define a number for global use
        number: 0.// Define a list for global use
        list: [{id: 1.name: '111' },
            { id: 2.name: '222' },
            { id: 3.name: '333'},]}});export default store;
Copy the code

Modify the main. Js:

import Vue from 'vue';
import App from './App';
import router from './router';
import store from './store'; // Import the store object we exported earlier

Vue.config.productionTip = false;

new Vue({
    el: '#app',
    router,
    store, // Add the store object to the vue instance
    components: { App },
    template: '<App/>'
});
Copy the code

Last modify app.vue:

<template>
    <div></div>
</template>

<script>
    export default {
        mounted() {
            // Use this.$store.state.XXX to access the state in the repository directly
            console.log(this.$store.state.name); }}</script>
Copy the code

At this point, start the project NPM run dev and print the value of name we just defined in store in the console.

  • ๐Ÿค– Official Recommendation 1:

This.$store.state.XXX is best placed in a calculated property, but I also recommend that you use it this way to make your code look more elegant, like this:

export default {
    mounted() {
        console.log(this.getName); 
    },
    computed: {getName() {
            return this.$store.state.name; }}},Copy the code

You can get the same effect as above.

  • ๐Ÿค– Official Recommendation 2:

This.$store.state.XXX () {this.$store.state.XXX () {this.$store.state.XXX ();

<script>
import { mapState } from 'vuex'; // Import mapState from vuex
export default {
    mounted() {
        console.log(this.name);
    },
    computed: {
        ...mapState(['name']), // After being deconstructed, it is automatically added to the calculated property and can be accessed directly as if it were a calculated property}},</script>
Copy the code

You can even give it nicknames as you deconstruct it, like this:

. mapState({aliasName: 'name' }),  // With aliases, objects are received instead of arrays
Copy the code

๐Ÿค— At this point, vuex installation and initialization are complete, and you can easily access the state of the repository from anywhere in the project

Step three, get to know the modifiers: getters

When you see this, prove that you have created a vUE project perfectly and installed vuex into it!

Good! Next, we introduce a Getter, a “modifier” for read operations

  • ๐Ÿคจ Imagine a scenario where you have displayed the store name on many pages, and the product manager comes to you for a problem ๐Ÿ˜ก :

  • Product Manager: All names must be preceded by “hello!”

  • Me: Why?

  • Product Manager: What else do I need to do to make a request?

  • Me: Good, I add!

At this point, your first thought is how to add, EMM… On each page, use this.$store.state.name to get the value and iterate, preceded by “hello”.

๐Ÿคฆ ๐Ÿป came ๏ธ wrong! This is bad for several reasons:

  • First, if you use name in A, B and C, then you need to modify the name in A, B and C, and you need to add this method many times in multiple pages, resulting in code redundancy, which is very bad.
  • Second, if the next time the product manager asks you to change the word “hello” to “fuck”, you have to change all three pages again and slap yourself in the face…

๐Ÿ‘๐Ÿป Learning from the above lessons, you will have a new idea: we can directly store some operations or processing of name, from the source to solve the problem! So how do you write that? At this point, the Getter is introduced!

How do I use ๐Ÿคก? No nonsense, show code!

First, add the getters property to the Store object

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

Vue.use(Vuex);

const store = new Vuex.Store({
    state: {
        name: 'Joe'.number: 0.list: [{id: 1.name: '111' },
            { id: 2.name: '222' },
            { id: 3.name: '333'}},],// Add the getters property to the store object
    getters: {
        getMessage(state) { // Get the modified name. The first argument, state, is required and must be written on the parameter
            return `hello${state.name}`; }}});export default store;
Copy the code

Use in components:

export default {
    mounted() {
        $store. State = $store. Getters = $store
        console.log(this.$store.state.name);
        console.log(this.$store.getters.getMessage); }}Copy the code

Then look at the console:

unproblematic

๐Ÿค– Official advice: $store. Getters.XXX (” this “, “this”, “this”, “this”, “this”); $store. Like this:

<script>
import { mapState, mapGetters } from 'vuex';
export default {
    mounted() {
        console.log(this.name);
        console.log(this.getMessage);
    },
    computed: {
        ...mapState(['name']),
        ...mapGetters(['getMessage']),}},</script>
Copy the code

Now you get the same effect as before.

Of course, like mapState, you can also get aliases and nicknames, like the following:

. mapGetters({aliasName: 'getMessage' }),  // With aliases, objects are received instead of arrays
Copy the code

๐Ÿค— OK, when you see here, you have successfully used getters, and you can understand when to use getters. You can access getters by calculating properties (caching), or methods (no caching), and you can even call getters from within the getters method. Of course, you can also implement a method like state, which uses mapGetters to deconstruct into calculated properties, so that you can easily use getters.

๐Ÿ˜Ž Read value operations we have “native read (state)” and “modified read (getters)”, next to introduce how to modify the value!

Step 4, learn how to change the value: Mutation

๐Ÿค— OK! First of all, congratulations on seeing this, so now that we’ve successfully accessed the value in Store, let me show you how to modify the value in state.

  • If you want to change the value, you can say:
// Error
this.$store.state.XXX = XXX;
Copy the code

๐Ÿคช First of all, here I make it clear: this is the wrong way to write! That’s the wrong way! That’s the wrong way!

Why is that wrong? Because the store is weird, you can take it, but you can’t change it. Let me give you an example:

๐Ÿค” If you open wechat circle of friends, see your friends sent a dynamic, but there is a typo in the dynamic, what should you do? Can you change it for him? Of course not! We can only inform him to modify, because it is someone else’s circle of friends, you have no right to operate, only he can operate. Similarly, in VUEX, we cannot directly modify the value in the warehouse, we have to use the method of VUEX to modify, at this time, Mutation appeared.

๐Ÿ˜ฌ After explaining the problem clearly, we are ready to accomplish an effect: We first output the default value 0 of number in state, and then we change the default value 0 of number by submitting Mutations in the VUE component to the value we want to change, and then output it, so that we can simply practice how to use Mutations. Cut the crap, go to the code.

  • Modify the store/index. Js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
    state: {
        name: 'Joe'.number: 0,},mutations: { // Add the nutations property
        setNumber(state) {  Add a mutations method, which changes num from 0 to 5, and state must be the default
            state.number = 5; }}});export default store;
Copy the code
  • Modify the App. Vue
<script>
export default {
    mounted() {
        console.log(` old values:The ${this.$store.state.number}`);
        this.$store.commit('setNumber');
        console.log(` new value:The ${this.$store.state.number}`); }},</script>
Copy the code
  • Run the project and view the console:

  • ๐Ÿคก is the method of simple realization of mutations, but there is no transfer. What if we want to transfer unfixed parameters? Here’s how to solve it

  • Modify the store/index. Js

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

Vue.use(Vuex);

const store = new Vuex.Store({
    state: {
        name: 'Joe'.number: 0,},mutations: {
        setNumber(state) {
            state.number = 5;
        },
        setNumberIsWhat(state, number) { // Add a mutations method with parametersstate.number = number; ,}}});export default store;
Copy the code
  • Modify the App. Vue
<script>
export default {
    mounted() {
        console.log(` old values:The ${this.$store.state.number}`);
        this.$store.commit('setNumberIsWhat'.Awesome!);
        console.log(` new value:The ${this.$store.state.number}`); }},</script>
Copy the code
  • Run the project and view the console:

No problem!

  • You can name an object as you like, but you can call it payload.

  • Modify the store/index. Js

mutations: {
    setNumber(state) {
        state.number = 5;
    },
    setNumberIsWhat(state, payload) { // Add the mutations method with parameters, and officially suggest payload as an objectstate.number = payload.number; }},Copy the code
  • Modify the App. Vue
<script>
export default {
    mounted() {
        console.log(` old values:The ${this.$store.state.number}`);
        this.$store.commit('setNumberIsWhat', { number: Awesome! });  // You also need to pass an object when calling
        console.log(` new value:The ${this.$store.state.number}`); }},</script>
Copy the code
  • You can get the same effect as before, and the code is more beautiful!

๐Ÿ˜ฑ here says an important principle: the function in Mutations must be synchronous operation, not asynchronous operation! (Don't worry, we'll talk about asynchrony later.)

๐Ÿ˜ฑ here says an important principle: the function in Mutations must be synchronous operation, not asynchronous operation! (Don't worry, we'll talk about asynchrony later.)

๐Ÿ˜ฑ here says an important principle: the function in Mutations must be synchronous operation, not asynchronous operation! (Don't worry, we'll talk about asynchrony later.)

Ok, with that important principle in mind, here’s a little trick:

  • ๐Ÿค– official suggestion: Just like the original mapState and mapGetters, we can use mapMutations instead of store.com MIT (‘XXX’) in the component. Isn’t that convenient?
<script>
import { mapMutations } from 'vuex';
export default {
    mounted() {
        this.setNumberIsWhat({ number: 999 });
    },
    methods: {   // Note that mapMutations deconstructs methods, not attributes. mapMutations(['setNumberIsWhat']),}},</script>
Copy the code
  • You get the same effect as before, and the code looks a little nicer!

  • You can also call it an alias, a nickname, like this:

methods:{ ... mapMutations({setNumberIsAlias: 'setNumberIsWhat' }),   // With aliases, objects are received instead of arrays
}
Copy the code
  • ๐Ÿค” OK, the introduction of Mutation is basically like this. In addition, you have also mastered how to write whether there is a parameter when defining the mutations method. And listen to the official advice, use mapMutations to deconstruct the methods inside your components, so you can easily use the mutations method!

  • ๐Ÿคช mentions that Mutations only work synchronously, so let’s move on to the next section on what to look out for when using Actions for asynchronous operations!

Step 5: Understand asynchronous operations: Actions

๐Ÿ˜† OK! In this section, we will learn to use Actions. The meaning of Actions is that if there is an asynchronous operation when you modify state, the author of VUEX does not want you to put the asynchronous operation in Mutations, so he sets an area for you to put the asynchronous operation, which is Actions

๐Ÿ˜› let’s go straight to the previous code

  • Modify the store/index. Js
const store = new Vuex.Store({
    state: {
        name: 'Joe'.number: 0,},mutations: {
        setNumberIsWhat(state, payload){ state.number = payload.number; }},actions: {   // Add an actions attribute
        setNum(content) {  // Add the setNum method. By default, the first parameter is content, whose value is a copy of the store
            return new Promise(resolve= > {  // We simulate an asynchronous operation and change the number to 888 after 1 second
                setTimeout(() = > {
                    content.commit('setNumberIsWhat', { number: 888 });
                    resolve();
                }, 1000); }); }}});Copy the code
  • Modify the App. Vue
async mounted() {
    console.log(` old values:The ${this.$store.state.number}`);
    await this.$store.dispatch('setNum');
    console.log(` new value:The ${this.$store.state.number}`);
},
Copy the code
  • Run the project and view the console:

(2) the action is the only one that has been uploaded for mutation. (3) the action is the only one that has been uploaded for mutation.

๐Ÿ˜ผ of course, you can do the following for mutation:

  • Modify the store/index. Js
actions: {
    setNum(content, payload) {   // Add the payload parameter
        return new Promise(resolve= > {
            setTimeout(() = > {
                content.commit('setNumberIsWhat', { number: payload.number });
                resolve();
            }, 1000); }); }},Copy the code
  • Modify the App. Vue
async mounted() {
    console.log(` old values:The ${this.$store.state.number}`);
    await this.$store.dispatch('setNum', { number: 611 });
    console.log(` new value:The ${this.$store.state.number}`);
},
Copy the code
  • Run the project and view the console

No problem at all!

  • ๐Ÿค– official tip 1: If you don’t want to call actions using this.$store.dispatch(‘XXX’), you can use mapActions to deconstruct the actions into methods and call this directly:
<script>
import { mapActions } from 'vuex';
export default {
    methods: {
        ...mapActions(['setNum']),   // Destruct into methods like this
    },
    async mounted() {
        await this.setNum({ number: 123 });  // Just call it like this}},</script>
Copy the code

Of course, you can also use nicknames, such as the following:

. mapActions({setNumAlias: 'setNum' }),   // With aliases, objects are received instead of arrays
Copy the code
  • ๐Ÿค– official recommendation 2: In the actions of store/index.js, the method parameters can be destructed directly to make subsequent operations easier:
actions: {
    setNum({ commit }) {   // Destruct the content structure to commit
        return new Promise(resolve= > {
            setTimeout(() = > {
                commit('XXXX');  // Call directly
                resolve();
            }, 1000); }); }},Copy the code
  • ๐Ÿค  OK, see here, you should understand the position of action in VUEX, when to use action, when not to use it, you must have your own judgment, the most important judgment condition is whether the operation I want to do is asynchronous, this is also the essence of action. Action is the next level up from mutation. After processing some of the asynchronous operations on the action, mutation is left to the mutation to change the state.

Step 6: Summary

๐Ÿค—! You install vuex, configure it, read state, and even modify getters, and then change the value. If you have an asynchronous operation and need to change state, you will be able to configure vuex. Use Action, and you can use vuex in your project! Come on! ๐Ÿค”