Background:

During requirements development, some interfaces return results that have many fields that need to be displayed on the page. These fields can usually be encapsulated as calculated properties in a.vue file or reassigned to fields in data for ease of use. As follows:

computed(){
  count1(){
	return this.targetObj.count1
  },
  count2(){
	return this.targetObj.count2
  },
  // ...
  // Just imagine. You have to write the same code five or ten times
}
Copy the code

But either way, there’s a lot of code redundancy, and it’s painful. In order to solve this phenomenon, this paper borrows the idea of using VUEX map method, which greatly reduces redundant code and can make unified fault tolerant processing for data acquisition.

The map method:

The basic method of state extraction in VUEX can be used in the following ways:

computed(){
  count(){
	return this.$store.count
  }
}
Copy the code

Vuex has also noticed that when there is a lot of data to be retrieved from the Store, this method can lead to huge code redundancy and duplicate code running around. You’ll see a lot of computational property definitions, as well as long link object property extraction. Therefore, VUEX defines a map method that is used to fetch specified store data in bulk. This map method is essentially a factory function (higher-order function) that produces a function of a particular form. MapState actually returns an object res. Each property in res is a method that returns the value in state.

  var mapState = normalizeNamespace(function (namespace, states) {
	// Define an object to store the methods that get the specified property
    var res = {};
    normalizeMap(states).forEach(function (ref) {
      var key = ref.key;
      var val = ref.val;
	  // Defines the method that gets the specified property of the specified object
      res[key] = function mappedState () {
        var state = this.$store.state;
        var getters = this.$store.getters;
		// Find the specified Store module object based on the namespace
        if (namespace) {
          var module = getModuleByNamespace(this.$store, 'mapState', namespace);
          if (!module) {
            return
          }
          state = module.context.state;
          getters = module.context.getters;
        }
		// Gets attributes in the Store Module obtained by specifying a namespace
        return typeof val === 'function'
          ? val.call(this, state, getters)
          : state[val]
      };
    });
	// Return the function object
    return res
  });
Copy the code

Application:

Following this idea, you can optimize how fields in a complex object are retrieved. The factory functions defined are shown below

export const mapTargetValue = (nameSpace, keyList = []) = >{
  const result = {}
  // Note: do not return the arrow function, otherwise you will not get this
  // Both forms of keyList are compatible. Refer to the use of attribute renaming in mapState
  if(Array.isArray(keyList)){
    keyList.forEach( key= > result[key] = function(){ 
		// We assume we can get the namespace object directly on this
		// Of course, the complexity of specifying object fetching depends on your code logic
		return this[nameSpace][key] || 0})}else if(typeof keyList === 'object' && keyList){
    for(let key in keyList){
      result[keyList[key]] = function(){ return this[nameSpace][key] || 0}}}return result
}
Copy the code

The defined use of this method is exactly the same as the use of mapState. Compared with the previous value method, it can greatly reduce the amount of repeated code. Specific applications are as follows

computed: { ... mapTargetValue("targetObj"["count1"."count2"]),
	...mapTargetValue("targetObj", { count1: "count3".count2: "count4"}}),Copy the code