31
头图

What is vuex

Official definition

state management mode developed specifically for Vue.js applications. It uses centralized storage to manage the state of all components of the application, and uses corresponding rules to ensure that the state changes in a predictable manner.

Beginner learning vuex, after reading this official definition, the black question mark, I feel that every word is known, but when they are together, it seems that they don’t understand. Okay, let's translate it in the vernacular. Supplement: When the official document defines a concept, it is indeed concise and concise, so there will be a situation where such a definition concept is slightly obscure.

Explain in the vernacular

  • state management mode specially developed for Vue.js applications

    Vuex is a plug-in (package) developed for the vue.js project. This plug-in (package) is mainly used for state management.

    Question: What is state management? State management manages state (it seems nonsense). In fact, in development, there is a commonly heard word that is state. What is state? We know that the bulb is on and off are a fixed state, we can use 1 to represent on, and 0 to represent off. In this case, the state can be represented by numbers. On the other hand, state is the specific manifestation of data, so we can understand it like this: state management is data management, and further, vuex is to manage the data in vue

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

    Lu Xun said: Vue is a componentized development, which is to split a page into small pieces. Each small piece must have its own data for presentation. For example, the drop-down box has data to choose from, and the table has the data to be presented in the table. Then these data can be directly placed in the data in the .vue file for management, but if it is a large project, the data in the .vue file to manage it is slightly lacking. Therefore: you can use vuex to uniformly store and manage the data of each component. Vuex is like a warehouse, used to store the data that needs to be used in the components. As for management, it is to add, delete, modify, and check, access, modify, delete and other operations in vuex
  • And use the corresponding rules to ensure that the state changes in a predictable way

    This sentence means that if you want to access, modify, or delete the state data in the vuex warehouse, you need to follow certain grammatical rules, such as action --> mutaion --> state Delete, modify, check, for example, use auxiliary functions such as add, delete, modify, and check the data in vuex. This specific rule will be explained one by one in the steps of using vuex below

So vuex is a warehouse for storing data. So we usually create a store folder when using vuex. The Chinese meaning of the word store means store or warehouse.

Application scenarios of vuex

  • Normal data can be placed in data to avoid trouble. Vuex is rarely used in small projects. After all, Vuex has a little more steps.
  • Generally, 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 tokens. Save a copy in vuex, save another copy in localstorage, fetch the data directly from vuex, and then fetch it from localstorage if you can't get it.
  • Data communication across many component levels can also be managed through vuex. After all, vuex is like an object. Many components point to this object. When this vuex object changes, the corresponding content in all components will change. In this way, real-time response can be achieved, one change, everyone changes

Steps for usage

First of all, we must build the project. The process of building the project will not be repeated. Once the project is built, we can use vuex according to the following steps

The first step is npm download and install the vuex plugin

Because vuex is a specific plug-in used to manage data in vue, according to the idea of a pluggable framework, if you want to use vuex, you can download and install it, and you can uninstall it when you don’t want to use it.
npm install vuex --save

The second step is to create a new store folder and register to use the vuex plugin

As shown below:

If the store object is mounted on the vue object, then every component can access the store object, then every component can use vuex

The printed vue instance object is as shown below

Take a look at the specific content of $store


Since the $store object of vuex mounted on the total instance of vue has our defined state, mutations, actions, getters, then we can access and use the data in vuex on each component through this.$store... . In this way, the sentence in the vuex document is verified: The state of all the components of the vuex application using a centralized storage management application, yes, they are all concentrated on the vue instance, and the state of all components can be accessed.

In fact, learning vuex is to learn two points:

  1. How to read warehouse data in vuex
  2. How to modify the data of the warehouse in vuex

The third step is to read the data of the warehouse in vuex

In the above code, we have defined a msg attribute in the state in vuex, and then post the code

export default new Vuex.Store({
    state:{
        msg:'我是vuex哦'
    },
    // 等...
})

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

A pair of parenthesis expressions are used directly (not recommended)

<h2>{{this.$store.state.msg}}</h2>
The first method is not very elegant, and it is generally not used. The second method or the third method are mainly used.

The second method is mounted to use the 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>

Method 3: Use computed to get the data in vuex

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

The fourth step is to modify the data in vuex

Generally, the data in vuex is modified in the callback function of the event. For example, we click a button to modify the data in vuex.

Method 1 direct modification (not recommended)

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

<script>
export default {
    methods: {
        // 直接赋值修改vuex中的state的数据
        changeVuex(){
            this.$store.state.msg = '修改vuex'
        },
    },
    computed: {
        msg(){ return this.$store.state.msg }
    }
}
</script>

This method can barely work, but vuex will report an error when strict mode is enabled. The code for enabling strict mode is as follows:

export default new Vuex.Store({
    strict:true, // 开启严格模式
    state:{
        msg:'我是vuex哦'
    },
    // 等...
})

The error message diagram is as follows:

Meaning of error message
Error:[vuex] do not mutate vuex store state outside mutation handlers.

Don't modify the state value in the store in vuex without passing the mutation operation

So from this we think of the sentence defined by : 160aa2eb937fa1 and use the corresponding rules to ensure that the state changes in a predictable way. The corresponding rule here means that if you want to modify the data in vuex, you must Follow the steps and flow rules for manipulating data in vuex, hehe, or I will report an error to you. So what are the rules for modifying state defined by vuex? Please see the picture below

Method two action-->mutation-->state

Let’s take a look at the official diagram

After reading the above picture, 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 actions to work, that is: dispatch actions

    (The component says: Hey, actions, I want to change the data in vuex, you send a request, get the data I want from the back-end interface to change it)

  • After the action gets the message, it will send a request to the backend to get the data returned by the backend. After the action gets the data returned by the backend, it submits the data commit to the mutations, that is: commit a mutation

    (After actions get the data, but they are also lazy, give the data to the warehouse manager mutations, and after telling you to change the corresponding data, it will be withdrawn)

  • Mutations are equivalent to the ultimate warehouse manager, who will modify the data in the vuex warehouse, namely: mutate the state

    (mutations work hard, just change the state data in vuex, after the change, wait for the next work, the process of mutations modifying data will be monitored by the warehouse, which is the development tool devTool of vue)

  • Vue data is responsive. As soon as the warehouse data is changed, the components that use the warehouse data will be rendered again, so the page effect will also change.
If the component is not an asynchronous request to change the data, you can also skip the actions directly and let the warehouse manager mutations directly modify the data, but this way is not too much

code show as below

// 组件
<template>
  <div class="box">
      <h2>{{msg}}</h2>
      <el-button @click="changeVuex">修改</el-button>
  </div>
</template>

<script>
export default {
    methods: {
        changeVuex(){
            this.$store.dispatch('actionsChange')
        },
    },
    computed: {
        msg(){ return this.$store.state.msg }
    }
}
</script>
// vuex
export default new Vuex.Store({
    strict:true,
    state:{
        msg:'我是vuex哦'
    },
    mutations:{
        // 这里第一个形参state就是仓库state,是可以访问到state里的msg的值,即 可以修改state
        // 第二个形参params是actions中传过来的数据
        mutationsChange(state,params){
            console.log(state,params);
            state.msg = params
        }
    },
    actions:{
        // 这里的形参store对象下面有commit方法
        // 可以去告知对应的mutations中的函数执行
        actionsChange(store){
            console.log(store);
            setTimeout(() => {
                store.commit('mutationsChange', '规范修改vuex')
            }, 500);
        }
    }
})

The effect diagram is as follows

devtool records the operations of mutations

Supplement getter processing

In the getter, we can define a function. This function is used to modify the value in the state. The function receives a parameter state. The state parameter is the current state object. Through this parameter, the data in the state can be processed, and the return is processed. For use in components

// vuex
export default new Vuex.Store({
    strict:true,
    state:{
        msg:'我是vuex哦'
    },
    getters:{
        gettersChange(state){
            return state.msg + '---getter修改state中的数据'
        }
    },
})

When used in the component, just use the data in the getter directly, as follows:
this.$store.getters.gettersChange
Of course, the getter is not necessary, that is, after the data in vuex is retrieved from the component, we will process it. But what can be processed in the getter is best processed in the getter, because it is more elegant to write code like this

Auxiliary function

The appearance of the function function is to allow us to write a few lines of code less. Let's take the state in vuex as an example. Suppose we need to get the value of multiple states in a component. In this case, this statement has to be written multiple times. this.$store.state.msg1, this.$store.state.msg2, this.$store.state.msg3, etc. To simplify, four auxiliary functions are encapsulated inside vuex, which correspond to the operations of state, mutations, actions, and getters.
auxiliary function, in short, is the syntactic sugar encapsulated by You Dao

Auxiliary functions are generally used with calculation attributes and methods

mapState helper function

The first step, suppose there are three data in the vuex warehouse, we need to use these three data on the component

// store.js
export default new Vuex.Store({
    state:{
            msg1:'辅助函数一',
            msg2:'辅助函数二',
            msg3:'辅助函数三',
          },
}

The second step is to introduce auxiliary functions from the vuex plugin
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'
The third step is to use the auxiliary function mapstate to get the data in the state in the calculation attribute

// 方式一,数组形式
computed: {
        ...mapState(['msg1','msg2','msg3'])
},
    
// 方式二, 对象形式(vuex模块化比较常用)
computed: {
    ...mapState({
        msg1: state=>state.msg1,
        msg2: state=>state.msg2,
        msg3: state=>state.msg3,
    })
},

In the fourth step, you can directly use it in the difference expression in the component

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

The fifth step, the page rendering is as follows

mapGetters helper function

The usage is basically the same as mapState

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

mapMutations helper function

For example, we trigger mutations in the callback function of the button click event. For comparison, there is a difference between using auxiliary functions and using auxiliary functions.
vuex structure

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

html structure

<template>
  <div>
    <h2>{{ msg }}</h2>
    <el-button @click="kkk('我是参数')">辅助函数mapActions</el-button>
  </div>
</template>

js code

<script>
import { mapState, mapMutations } from "vuex";
export default {
  computed: {
    ...mapState(["msg"]),
  },
  methods: {
    // 不使用辅助函数的写法
    kkk(params) {
      this.$store.commit("kkk", params);
    },
      
    // 使用辅助函数的写法
    ...mapMutations(["kkk"]),
  },
};
</script>

Note: When using auxiliary functions, it seems that there is no place to pass parameters. In fact, auxiliary functions help us pass them silently. This parameter needs to be written in the click statement in the html structure, such as the above code: <el-button @click=" kkk('I am a parameter')">helper function mapActions</el-button>

mapActions helper function

The usage of mapActions is basically the same as that of mapMutations, just change the word, so I won’t repeat it here.
...mapActions(["sss"])
Means: to trigger the sss function in Actions

Module modularization of vuex

When it comes to modularity, the idea is still the same, big and small, easy to manage. Many languages have modular applications, and so does vuex. Just imagine, if all the status data are written together, it is easy to be dazzled and inconvenient to manage. Therefore, in the design of vuex, you have done modular module processing

Graphical steps

Use vuex modularization in components

Get the data in the vuex module

Here is an example of obtaining the data in the state. The writing method of obtaining the data in the getters is basically the same.

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

<script>
import { mapState } from 'vuex'
export default {
  name: "CodeVue",
  computed: {
    // 正常方式
    msg(){
      return this.$store.state.vue.module// 找state里的vue模块下的module的值
    },
      
    // 使用辅助函数方式,这里用对象的写法
    ...mapState({
      msg:state=>state.vue.module// 找state里的vue模块下的module的值
    })
  }
};
</script>

Print the store object, you can see the corresponding value

Modify the data in the vuex module

Take triggering mutations as an example, the writing of actions is basically the same, so I won’t go into details

  • No helper function

<template>
<div>

<h2>{{ msg }}</h2>
<el-button @click="moduleChange">模块化修改值</el-button>

</div>
</template>

<script>
export default {
name: "CodeVue",
computed: {

...mapState({
  msg:state=>state.vue.module
})

},
methods: {

moduleChange(){
  // 注意,直接提交对应模块的方法即可,commit会自动找到对应vuex下的方法
  this.$store.commit('moduleChange','我是参数')
}

},
};
</script>

- 使用辅助函数
  

<template>
<div>

<h2>{{ msg }}</h2>
<!-- 我们在点击事件的语句中,把data中定义的参数带过去,去提交mutations -->
<el-button @click="moduleChange(canshu)">模块化修改值</el-button>

</div>
</template>

<script>
import { mapState, mapMutations } from 'vuex'
export default {
name: "CodeVue",
data() {

return {
  canshu:'我是参数'
}

},
computed: {

...mapState({
  msg:state=>state.vue.module
})

},
methods: {

...mapMutations(['moduleChange'])

},
};
</script>

> 注意,上述我使用vuex的模块化module的时候,没有加上命名空间`namespace`,所以去提交对应模块下的mutations的时候,可以直接写`this.$store.commit('moduleChange','我是参数')`或`...mapMutations(['moduleChange'])`这样的话,vuex会去自己所有模块下去找`moduleChange`这个函数,然后去修改。这样的话,略微浪费性能,因为,默认情况下,vuex模块内部的 action、mutation 和 getter 是挂载注册在**全局命名空间**的,这样使得多个模块能够对同一 mutation 或 action去操作,就不停的找,直到找到为止。但是一般情况下,我们使用vuex模块化的时候都会加上命名空间,做到独立、复用。接下来我们说一下,vuex模块化的标准用法,即加上命名空间的用法

### 命名空间
- 不加命名空间,所有的都找一遍。
- 加了的话,只去特定的模块找
- 所以使用命名空间的话,提交mutations写法就变了

### 写法如下

// Do not use auxiliary functions
moduleChange(){

this.$store.commit('vue/moduleChange'); // 以斜杠分割,斜杠前写对应模块名,斜杠后写对应mutations中的方法名

}

// Use helper functions
...mapMutations('vue',['moduleChange']) // Separate by commas, write the module name before the comma, and an array after the comma, and place the method name in the corresponding mutations in the array

//3. Under alias state
...mapMutations({

anotherName:'vue/moduleChange' // 和不使用辅助函数一样

}),

## 总结
让我们还回到vuex官网下定义的那句话:

`Vuex 是一个专为 Vue.js 应用程序开发的**状态管理模式**。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化`

貌似这样定义还挺好的,科学严谨...

最后一首打油诗送给各位看官,娱乐一下,哈哈

 《码破苍穹》
码宗强者名尤大
代码化翼走天下
随手祭出VUE
恐怖如斯真可怕
笔者码渣虽技薄
但却心中有梦呀
还望各位大佬们
点赞鼓励一下哈

水冗水孚
1.1k 声望588 粉丝

每一个不曾起舞的日子,都是对生命的辜负