What is a vuex

The official definition of

Vuex is a state management mode developed specifically for vue.js applications. It uses centralized storage to manage the state of all components of an application and rules to ensure that the state changes in a predictable way.

When I first learned Vuex, after reading this official definition, I felt that I knew every word, but when they were combined together, I didn’t seem to understand it. Ok, so let’s translate it in plain English. Addendum: When defining a concept in an official document, it is really intended to be concise and concise, so it can be slightly obscure

Explain in plain English

  • Vuex is a state management mode developed specifically for vue.js applications

    Vuex is a plug-in (package) developed for vuue.js project, which is mainly used for state management.

    Q: what is state management? State management is state management. In fact, one of the most common words heard in development is state. We know that bulb on and off is a fixed state respectively. We can use 1 to represent on and 0 to represent off. In this case, states can be represented by numbers, and in turn, states are concrete representations of data, so we can understand that state management is data management, and further, VUEX is to manage data in VUE

  • It uses centralized storage to manage the state of all components of the application

    Lu Xun said: VUE is a component development, that is, a page is divided into small pieces. Each piece must have its own data to present. For example, drop-down boxes have drop-down boxes to select data, and tables have table data to present. The data can be managed directly in the data file in the.vue file, but if it is a large project, the data in the.vue file is not managed properly. Therefore: VuEX can be used to store and manage the data of each component in a unified manner. Vuex is like a warehouse for storing the data needed in the components. As for management, it means adding, deleting, modifying and checking, accessing, modifying, deleting and other operations in VUex

  • And the corresponding rules ensure that the state changes in a predictable way

    In order to access, modify, and delete state data in vuex warehouse, it is necessary to follow certain grammatical rules, such as action–>mutaion–>state to add, delete, modify, and query, for example, using auxiliary functions such as add, delete, modify, and query vuex data. This specific rule will be explained in the vuEX usage steps below

So vuEX is a repository for data. Therefore, when using Vuex, we usually create a store folder. The Chinese word store means store and warehouse

Application scenarios of VUEX

  • Normal data can be put into data, so as to avoid trouble. Generally, vuEX is rarely used in small projects. After all, VUEX has a little more steps
  • In general, it is better to put public data in VUEX. After all, components have their own data to store data and public variables such as user information and token. Vuex store one copy, localStorage store another copy, get data directly from VUex, can not get from localstorage again.
  • Data communication across many component levels can also be managed through VUEX. After all, VUEX is like one object, and many components point to this object. When the vuEX object changes, the corresponding content of all components will change, so that real-time response can be achieved

Using the step

First of all, we need to set up the project. The process of setting up the project is not described here. Once the project is set up, we can use VUEX as follows

Step 1 NPM download and install the Vuex plug-in

Because Vuex is a plug-in specifically designed to manage data in a VUE, the idea of a pluggable framework is to download and install vuex if you want to use it, and uninstall it when you don’t

npm install vuex --save
Copy the code

Step 2 Create a Store folder and register using the Vuex plugin

The diagram below:

By attaching the Store object to the VUE object, each component can access the Store object, and each component can use vuex

The printed vUE instance object is shown in the following figure

Take a look at the details of $Store

State, mutations, Actions, and getters are included in the vuex $$Store object, which is attached to the total instance of vue. The vuEX data can then be accessed and used on various components. In this way, the vuex documentation proves that vuex uses centralized storage to manage the state of all components of the application. Yes, the state of all components is centralized on the VUE instance and accessible.

In fact, learning VUex is to learn two points:

  1. How do I read warehouse data in VUEX
  2. How do I modify warehouse data in VUEX

The third step reads the warehouse data in vuEX

In the above code, we have defined a MSG property in the state of vuex. Post the code again

export default new Vuex.Store({
    state: {msg:'I'm Vuex.'
    },
    / /...
})
Copy the code

Next we use this data in the component and render it on the page

Mode a double parenthesis expression used directly (not recommended)

{{this.$store.state. MSG}}

Mode 2 Mounted to retrieve data in VUEX

<template>
  <div class="box">
      <h2>{{msg}}</h2>
  </div>
</template>
<script>
export default {
    data() {
        return { msg:' '}},mounted() {
        this.msg = this.$store.state.msg
    },
}
</script>
Copy the code

Method three uses computed to fetch data from vuEX

<template>
  <div class="box">
      <h2>{{msg}}</h2>
  </div>
</template>
<script>
export default {
    computed: {
        msg(){ return this.$store.state.msg }
    }
}
</script>
Copy the code

Step 4 Modify the data in vuEX

This is usually done in the event callback function to modify the vuex data, for example, we click a button to modify the vuex data

Method 1: Direct Modification (not recommended)

<template>
  <div class="box">
      <h2>{{msg}}</h2>
      <el-button @click="changeVuex">Modify the</el-button>
  </div>
</template>

<script>
export default {
    methods: {
        // Direct assignment modifies state data in vuex
        changeVuex(){
            this.$store.state.msg = 'modify vuex'}},computed: {
        msg(){ return this.$store.state.msg }
    }
}
</script>
Copy the code

This works just fine, but vuex will report an error when strict mode is enabled.

export default new Vuex.Store({
    strict:true.// Enable strict mode
    state: {msg:'I'm Vuex.'
    },
    / /...
})
Copy the code

The error information graph is as follows:

Error message meaning

Error:[vuex] do not mutate vuex store state outside mutation handlers.

Do not change the state value of a VUEX store without mutation

So this brings us to the vuEX definition: to ensure that the state changes in a predictable way with the corresponding rules. The corresponding rules here mean that if you want to modify the data in VUEX, you need to follow the procedures of manipulating the data in VUEX, or you will get an error. So what are the rules for changing state defined by VUEX? Please see below

Way 2 action – > mutation – > state

Let’s take a look at the official illustration

After looking at the picture above, we can summarize the rules of using VUex as follows

  • The component wants to change the data in vuex, but the component itself just verbally summons the actions, i.e. dispatch the actions(Component says: Hey Actions, I'm going to change the data in vuex, you send a request, get the data I want from the back end interface and change it)
  • Once the action receives the message, it sends a request to the back end to obtain the data returned by the back end. After receiving the data, the action submits the data to mutations, which is called commit(After Actions got the data, but was also lazy, gave it to warehouse administrator Mutations, told them to change the corresponding data, and withdrew.)
  • Mutations are equivalent to the ultimate warehouse manager, who changes the data in the VUex warehouse, namely, mutate the state(Mutations works hard, and changes the data of state in VUEX. After the changes, it will wait for the next work. The process of mutations' data modification will be recorded by the monitoring of the warehouse, that is, devTool, the development tool of VUE.)
  • Vue data is responsive, and as soon as the warehouse data changes, the corresponding components that use the warehouse data will be re-rendered, so the page effect will change

Instead of sending asynchronous requests to change data in a component, it’s possible to skip actions and ask the warehouse administrator for mutations to change data, but that’s not too much

The following code

/ / component
<template>
  <div class="box">
      <h2>{{msg}}</h2>
      <el-button @click="changeVuex">Modify the</el-button>
  </div>
</template>

<script>
export default {
    methods: {
        changeVuex(){
            this.$store.dispatch('actionsChange')}},computed: {
        msg(){ return this.$store.state.msg }
    }
}
</script>
Copy the code
// vuex
export default new Vuex.Store({
    strict:true.state: {msg:'I'm Vuex.'
    },
    mutations: {// The first parameter state is the repository state, which is the value of MSG that can be accessed in state
        // The second parameter params is the data passed from actions
        mutationsChange(state,params){
            console.log(state,params);
            state.msg = params
        }
    },
    actions: {// There is a commit method under the parameter store
        // Go and tell the corresponding function in mutations to execute
        actionsChange(store){
            console.log(store);
            setTimeout(() = > {
                store.commit('mutationsChange'.'Specification modified vuex')},500); }}})Copy the code

The renderings are as follows

Devtool records the operation of mutations

Supplementary getter processing

In the getter, we can define a function that we use to modify the value of state. The function takes a parameter state, which is the current state object, and uses this parameter to process the data in state and return it for use in the component

// vuex
export default new Vuex.Store({
    strict:true.state: {msg:'I'm Vuex.'
    },
    getters: {gettersChange(state){
            return state.msg + '-- Getter modifies data in state '}}})Copy the code

When used in a component, just use the data in the getter as follows:

this.$store.getters.gettersChange

You can also do without getters, which means that after you get the vuEX data from the component, you can process it. But the best thing you can do in the getter is to do it in the getter, because it’s more elegant to write code that way

Auxiliary function

Let’s take the vuex state as an example. Let’s say we need to fetch multiple states in a component. In this case, the statement must be written multiple times. Msg1; this.$store.state.msg2; this.$store.state.msg3; For simplicity, vuEX internally packages four auxiliary functions, corresponding to the operations of state, mutations, Actions and getters respectively. Helper functions, in short, are syntactic sugar wrapped by Yo

Helper functions are usually used with computed properties and methods

MapState helper function

The first step is to assume that there are three pieces of data in the VUEX repository that we need to use on the component

// store.js
export default new Vuex.Store({
    state: {msg1:'Auxiliary function one'.msg2:'Auxiliary function two'.msg3:'Auxiliary function three',}}Copy the code

Step 2, import {mapState, mapMutations, mapActions, mapGetters} from ‘vuex’ Use the helper function mapState in the calculation properties to fetch data from state

// The first method is an array
computed: {
        ...mapState(['msg1'.'msg2'.'msg3'])},// Object form (vuEX modular is more commonly used)
computed: {
    ...mapState({
        msg1: state= >state.msg1,
        msg2: state= >state.msg2,
        msg3: state= >state.msg3,
    })
},
Copy the code

The fourth step is to use the difference expression directly in the component

<template>
    <div>
        <h1>{{msg1}}</h1>
        <h2>{{msg2}}</h2>
        <h3>{{msg3}}</h3>
    </div>
</template>
Copy the code

The fifth step, the page rendering is as follows

MapGetters helper function

Use it in the same way as mapState

computed:{ ... mapGetters(['msg']),}Copy the code

MapMutations auxiliary function

For example, let’s trigger mutations in the callback function of the button click event, and compare that with writing the vuEX structure using the syntax of the auxiliary function instead of using the auxiliary function

mutations:{
    kkk(state,params){
        state.msg = params
    }
},
Copy the code

HTML structure

<template>
  <div>
    <h2>{{ msg }}</h2>
    <el-button @click="KKK (' I am the parameter ')">The auxiliary function mapActions</el-button>
  </div>
</template>
Copy the code

Js code

<script>
import { mapState, mapMutations } from "vuex";
export default {
  computed: {
    ...mapState(["msg"]),},methods: {
    // Do not write auxiliary functions
    kkk(params) {
      this.$store.commit("kkk", params);
    },
      
    // use the auxiliary function. mapMutations(["kkk"]),}}; </script>Copy the code

Note: with the auxiliary function, there seems to be no place to pass the parameter. In fact, the auxiliary function silently passes the parameter. This parameter needs to be written in the HTML structure in the click statement, as shown in the above code:

MapActions helper function

The usage of mapActions and mapMutations is basically the same, just change a word, and I will not repeat it here

. mapActions(["sss"])

Trigger the SSS function in Actions

Vuex module module

Mention modular, thought or that sentence, big and small, easy to manage. Many languages have modular applications, and vuex is no different. Imagine if all the state data were written together, which would be confusing and difficult to manage. Therefore, In the design of VUEX, You made a modular module

The illustration step

Use VUex modularity in components

Get the data in vuEX module

Here, the data acquisition in state is taken as an example, and the data acquisition in getters is basically written in the same way

<template>
  <div>
    <h2>{{ msg }}</h2>
  </div>
</template>

<script>
import { mapState } from 'vuex'
export default {
  name: "CodeVue".computed: {
    // Normal mode
    msg(){
      return this.$store.state.vue.module// find the value of module under vue module in state
    },
      
    // Use the auxiliary function method. mapState({msg:state= >state.vue.module// find the value of module under vue module in state})}};</script>
Copy the code

Print the Store object, and you can see the corresponding value

Modify the data in the VUEX module

Here, take triggered mutations as an example, the writing method of actions is basically the same, without further elaboration

  • Do not use helper functions

    <template>
      <div>
        <h2>{{ msg }}</h2>
        <el-button @click="moduleChange">Modularization modified value</el-button>
      </div>
    </template>
    
    <script>
    export default {
      name: "CodeVue".computed: {
        ...mapState({
          msg:state= >state.vue.module
        })
      },
      methods: {
        moduleChange(){
          Commit (vuEX); commit (vuEX)
          this.$store.commit('moduleChange'.'I'm a parameter')}}};</script>
    Copy the code
  • Use auxiliary functions

    <template>
      <div>
        <h2>{{ msg }}</h2>
        <! We bring the parameters defined in data in the click event statement, and submit mutations -->
        <el-button @click="moduleChange(canshu)">Modularization modified value</el-button>
      </div>
    </template>
    
    <script>
    import { mapState, mapMutations } from 'vuex'
    export default {
      name: "CodeVue".data() {
        return {
          canshu:'I'm a parameter'}},computed: {
        ...mapState({
          msg:state= >state.vue.module
        })
      },
      methods: {
        ...mapMutations(['moduleChange'])}};</script>
    Copy the code

Note that I use vuex’s modular module above without adding a namespace, so when submitting mutations for the corresponding module, I can write this. parked store.com MIT (‘moduleChange’,’ I am a parameter ‘) or… MapMutations ([‘moduleChange’]), vuex will go to all its modules to find the moduleChange function and modify it. This is a slight waste of performance because, by default, actions, mutations, and getters inside the VUEX module are mounted and registered in the global namespace, allowing multiple modules to operate on the same mutation or action and keep looking until they find one. But in general, when we use VuEX modularity, we add a namespace to make it independent and reusable. Next, let’s talk about the standard use of vuex modularity, plus the use of namespaces

The namespace

  • No namespace, just find everything.

  • If so, only look for specific modules

  • So using the namespace, submit mutations changes the way you write it

Write the following

// Do not use auxiliary functions
moduleChange(){
    this.$store.commit('vue/moduleChange'); // Divide with a slash. Write the corresponding module name before a slash, and write the method name in mutations after a slash
}
    
// Use the helper function. mapMutations('vue'['moduleChange']) // Divide by comma. Before comma, write the module name, and after comma is an array, which places the method name corresponding to mutations

//3. In alias state. mapMutations({anotherName:'vue/moduleChange' // The same as not using helper functions
}),
Copy the code

conclusion

Let’s go back to the sentence defined on vuex’s website:

Vuex is a state management mode developed specifically for vue.js applications. It uses centralized storage to manage the state of all components of an application and rules to ensure that the state changes in a predictable way

It seems to be a good definition, scientific rigor…