vuex source code analysis (six) helper Detailed

For the state, getter, mutation, action, the time if each use with all this. $ Store.state, this. $ Store.getter and other references, would be more trouble, the code duplication and redundancy, we can assist function to help us to generate code, the auxiliary function has the following four:

    mapState (namespace, map); for acquiring State
    mapGetters (namespace, Map); for acquiring getters
    mapMutations (namespace, Map); for acquiring mutations
    mapActions (namespace, Map); for acquiring actions

Each of the auxiliary functions can take two parameters:

  namespace; namespace, which is the module name

  map; to get information

map in two ways, the object may be (key name is the name of the current variable settings Vue example, the value of the variable is to be acquired from the store names), or an array of strings (acquired at this time and set the variable named the same).

NOTE: auxiliary functions need to be injected at the root node store

ps: Many novice may only use an auxiliary function, do not know you can also use this $ store.state, this $ store.getter these usages ....

These auxiliary function returns an object, we can fit the object ES6 deployment operator, we can greatly simplify the writing , for example:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
    <script src="https://unpkg.com/[email protected]/dist/vuex.js"></script>
</head>
<body>
    <div id="app">
        <p>{{no}}</p>
        <p>{{No}}</p>
        <button @click="test1">测试1</button>
        <button @click="test2">测试2</button>
    </div>
    <script>
        const store = new Vuex.Store({
            state:{no:100},
            getters:{
                No:function(state){return state.no+100}
            },
            mutations:{
                increment(state,payload){state.no+=payload.no;}
            },
            actions:{
                increment({commit},info){
                    setTimeout(function(){
                        commit('increment',info)
                    },500)
                }
            }
        })
        var app = new Vue({
            el:"#app",
            store,
            computed:{
                ...Vuex.mapState(['no']),
                ...Vuex.mapGetters(['No'])
            },
            methods:{
                ...Vuex.mapMutations(['increment']),
                ...Vuex.mapActions({increment1:"increment"}),
                test1(){
                    this.increment({no:100})
                },
                test2(){
                    this.increment1({no:200})
                }
            }
        })  
    </script>
</body>
</html>

writer by: Desert QQ: 22969969

I feel it, if vuex used in the attribute bit more better, If only one state might as well use this. $ Store.state to get it, after all, in the node environment also need to {Import mapState } from ' vuex 'to get the exported symbols, you can see the page specific needs choose the right method.

 

Source code analysis


 All auxiliary functions in the same format vuex, is performing a normalizeNamespace () function, passing in an anonymous function, the anonymous function with two parameters, namely the namespace and map, in mapState example, as follows:

var mapState = normalizeNamespace ( function (namespace, States) {         // State helper name: Namespace states: For example: count2: "COUNT" 
  var RES = {}; 
  normalizeMap (States) .forEach ( function (REF) {                              // states to convert an object format, for example: [{Key: count2, Val: COUNT}] 
    var Key = ref.key;
     var Val = ref.val; 

    RES [Key] = function mappedState () {                                       // calculated corresponding to the attribute is a function, this function within the Vue example is directed 
      var State = the this.$store.state;                                              //获取state对象
      var getters = this.$store.getters;                                          //获取getters对象
      if (namespace) {
        var module = getModuleByNamespace(this.$store, 'mapState', namespace);
        if (!module) {
          return
        }
        state = module.context.state;
        getters = module.context.getters;
      }
      return typeof=== Val 'function'                                         
        val.call (? the this , state, getters)                                       // state is a logic function, the obtaining sub-module performs here state 
        : state [Val]                                                           // return state [Val], also is the value 
    };
     // Mark vuex getters for DevTools 
    RES [Key] = .vuex to true ; 
  }); 
  return RES 
});

normalizeNamespace is a uniform entry format for all auxiliary functions, as follows:

function normalizeNamespace (Fn) {                           // return an anonymous function takes two parameters, respectively, and mapping namespace, a parameter may be omitted 
  return  function (namespace, Map) {
     IF ( typeof namespace! == 'String') {                           / / If parameter 1 is not a character string (i.e., ignoring the namespace) 
      Map = namespace;                                               // the correction parameter is 1 Map 
      namespace = '';                                                // reset namespace null 
    } the else  IF (namespace.charAt (namespace.length ! -. 1) == '/' ) { 
      namespace + = '/' ; 
    } 
    returnfn (namespace, Map)                                      // last performed function fn 
  } 
}

Several other auxiliary functions are similar, it is to achieve a slightly different function within the pass normalizeNamespace.

Guess you like

Origin www.cnblogs.com/greatdesert/p/11430122.html