Some pundits will say that VUex is a product of history, but I really disagree. No reply.

Suggest beginners step by step, do not pretend B, after all, we are standing on the shoulders of giants

Five attributes of Vuex

** brief introduction: In order to let beginners have a concept of cognition, the following introduction is only illustrated in plain English, ** details please refer to the official website vuex.vuejs.org/zh/guide/

The key to Vuex is the Store object, which is at the heart of Vuex. Vuex is essentially a store object. Each Vue application has only one store object.

const store = new Vuex.Store({ state: {}, mutations: {}, actions: {}, modules: {} });

Vuex.Store can be thought of as a global storage object, which has five important properties as shown below, each of which serves its own purpose and can be used in concert with each other. Here’s what they do.

1.State :

The data source that holds data

Definition:

Const store = new vuex. store ({state: {List:[1,2,3,4,5,6,7]}})Copy the code

Components used in:

<script>
  export default {
    computed: {
      list() {
        return this.$store.state.List.filter(item => item > 3);      }
    }
 }
</script>
Copy the code

Results:

Get the List array from the data source and filter it. The output result is [4,5,6,7].

What if other components also need this filtered data? Maybe you’ll copy that line of code and put it in the component that you need. Then the question comes again. What if Party A’s father change demand >3 to >6? Do you need to modify each component sequentially, which is definitely more work. How to solve this problem, please read on.

2.Getter :

Derive some state from state in store, such as filtering List in state

Definition:

Const store = new vuex. store ({state: {List:[1,2,3,4,5,6,7]}, getters: {getListMax: state => { return state.List.filter(item => item > 3) } } })Copy the code

Components used in:

<script>
  export default {
    computed: {
      list() {
        return this.$store.getters.getListMax
        }
    }
  }
</script>
Copy the code

This solves the problem in **(1). If the requirements change, just go to getListMax and make the change in getters

3. Note :Getter dependencies

Getters can depend on other getters that have already been defined

Definition:

const store = new Vuex.Store({ state: { list: [1, 2, 3, 4, 5, 6, 7] }, getters: { getListMax: state => { return state.List.filter(item => item > 3) }, listCount: (state, getters) => { return getters.getListMax.length; }}})Copy the code

Components used in:

<script>
  export default {
    computed: {
      list() {
        return this.$store.getters.getListMax
      },
      listCount() {
        return this.$store.getters.listCount
     }    }
  }
</script>
Copy the code

The output is: list [4,5,6,7] length 4

4.Mutation: 

The only way to change the data source in state;

Mutation must be a synchronization function:

Deepen understanding may refer to: 1. www.jianshu.com/p/d071e205b… 2. www.zhihu.com/question/48…

Of course, you must write asynchronous and no one stops you, but the national law, the family has rules, in the path of programming learning, or to follow the pace of the regular army.

Definition:

Each mutation has a string event type (type) and a callback handler (handler).

const store = new Vuex.Store({ state: { List: [1, 2, 3, 4, 5, 6, 7]}, mutation:{// Event type (type) : "changeList" changeList(state,payload) {// Callback function (handler) : Is where we actually make the state change, and it will accept state as the first parameter state.list [0]=99+ paypay.num}}})Copy the code

Components used in:

Pass an extra parameter, the payload of mutation, to store.mit: in most cases, the payload is an object

<script>
  export default {
     created:{
        this.startMu()
        console.log(this.$store.state.List[0])
     },
     methods: {
        startMu(){
            this.$store.commit('changeList',{
                num:1
            })
        }
     }
  }
</script>
Copy the code

The method of invocation can also be written as

This. codestore.mit ({type:'changeList',//type attribute pointing to num:1})Copy the code

Output result: 100;

5.Action :

The Action commits mutation and changes the data in the state by mutation.

Actions can contain any asynchronous operation

Definition:

const store = new Vuex.Store({
  state: {
    List: [1, 2, 3, 4, 5, 6, 7]
  },
  mutation:{
      changeList(state,payload) {  
      state.List[0]=99+payload.num   
    }
  },
  actions: {
      changeListAsync (context) {
        return new Promise((resolve, reject) => {
            context.commit('changeList',{num:1})
         }).catch(error => {
            reject(error)
      })
    }
 }})
Copy the code

Components used in:

<script>
  export default {
     created:{
        this.startAc()     },
     methods: {
      startAc(){
        this.$store.dispatch('changeListAsync')
        }
     }
  }
</script>
Copy the code

The result is the same as in (4),

In the application of practical scenarios, the simultaneous operation of mutations alone cannot meet the actual demand. Vuex’s Acitons can solve this problem, and can perform asynchronous operation, which is used to solve the problem that mutations have only synchronous and indistinctive steps

6. Extension operators (…) Vuex attribute mapping is realized with auxiliary functions

(1.) Auxiliary functions :mapState, mapGetters, mapActions, mapMutations **(2).**mapState as an example, the rest can be baidu, the purpose is the same, reduce the repeatability of the code, improve the writing efficiency:

Definition:

const store = new Vuex.Store({
  state: {
    a:1,
    b:2,
    c:3
  }
})
Copy the code

Components used in:

<template> <div>{{this.a}}</div> <div>{{this.b}}</div> </template> <script> export default { computed: { ... mapState(['a','b','c']), } } </script>Copy the code

. MapState ([‘a’,’b’,’c’]), which is equivalent to the following code, significantly improves code writing efficiency.

 <template>
  <div>{{this.a}}</div> 
  <div>{{this.b}}</div>
</template>
<script>
  export default {
    computed: {
       a(){
          return this.$store.state.a
        },
        b(){
          return this.$store.state.b
        }
        ....
    }
 }
</script>        
Copy the code

Note: The previous method name is the same as the obtained attribute name.

7.Module:

The actual development assumes that only one stroe is used, and over time the amount of code in Sotre becomes very bloated.

To solve this problem, Vuex allows us to split the Store into modules. Each module has its own state, mutation, action, getter, and even nested submodules — split the same way from top to bottom.

This description on the official website is nonsense, and this attribute of Vuex is best understood.

But how to elegantly configure this property? Read on

Dynamically configure vuex.store

1. Create a Modules folder under the Store directory to store multiple modules, as shown in the following figure

2. Create a user.js module in the Modules folder.

Take user login as an example:

Users can submit information such as user names and passwords on the front-end page to the background. The token returned by the background and stored in vuEX.

To make it easier for beginners to understand, simplify the code in user.js as follows:

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * (state, token) => { state.token = token } } const actions = { login({ commit }, userInfo) { const { username, password } = userInfo return new Promise((resolve, reject) => { login({ username: username.trim(), password: password }).then(response => { commit('SET_TOKEN', data.token) resolve() }).catch(error => { reject(error) }) }) }, } export default {namespaced: true,// define the namespace state, mutations, actions}Copy the code

After the module is created, we learned from 1 that there are many similar modules in the modules folder. Let’s configure these modules in a unified way

3. Configure vuex modules

(1). Open index.js under store, code is as follows

import Vue from 'vue' import Vuex from 'vuex' import getters from './getters' Vue.use(Vuex) Const modulesFiles = require.context('./modules', true, /\.js$/) // dynamically configure the vuex. Store core code -start // traverses the module file, all the individual modules, summarized into vuex specification modules modulesFiles.keys().reduce((modules, modulePath) => { const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1') const Value = modulesFiles(modulePath) modules[moduleName] = value.default // Console prints console.log("modulePath",modulePath) console.log("moduleName",moduleName) console.log("value",value) return modules }, {}) // dynamically configure vuex.store core code -end console.log("modules",modules) // console print // ues Vuex.Store({ modules, getters }) export default storeCopy the code

The console modules displays the following information, indicating that the dynamic configuration is successful

Basic knowledge

Reduce definitionAnd * * * *Think about reduce application scenarios

4. Use Actions in your component via the Namespaced property

In the created user.js module we declare the namespace namespaced: true, which allows us to use the

Called from various components of the project as follows:

this.$store.dispatch('user/login', parm)

Parm is the parameter passed

Note: because it is a modular store with dynamic configuration, it avoids the problem of naming conflicts between different modules, so it is used

Namespaced :true, where user in user/login is the module name