头图

background:

In the process of requirement development, some interfaces return results with many fields need to be displayed on the page. Usually these fields can be encapsulated in the .vue file as calculate the attribute , or the corresponding fields can be re-assigned to the fields in data to achieve the purpose of ease of use. as follows:

computed(){
  count1(){
    return this.targetObj.count1
  },
  count2(){
    return this.targetObj.count2
  },
  // ...
  // 想象一下。你要写 5 遍 或者 10 遍类似的代码
}

But no matter which method, it will bring lot of code redundancy , which is extremely uncomfortable. In order to solve this phenomenon, this article borrows the idea of using the map method in vuex. The greatly reduces the redundant code , and can do unified fault-tolerant processing for data acquisition.

map method:

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

computed(){
  count(){
    return this.$store.count
  }
}

At the same time, vuex also noticed the problem. When there is a lot of data to be obtained in the store, this method will generate a huge code redundant , repeating the code everywhere. You will see large number of calculated attributes, as well as long link object attributes extraction. Therefore, vuex defines a map method to obtain the specified data in the store in batches.
This map method is actually a factory function (high-order function) , which is used to produce a specific form of function. The following is the source code. As you can see, mapState will eventually return an object res. Each property in res is a method, and this method returns the value in state.

  var mapState = normalizeNamespace(function (namespace, states) {
    // 定义一个对象 用于存储 获取指定属性的方法
    var res = {};
    normalizeMap(states).forEach(function (ref) {
      var key = ref.key;
      var val = ref.val;
      // 定义 获取指定对象中指定属性的方法
      res[key] = function mappedState () {
        var state = this.$store.state;
        var getters = this.$store.getters;
        // 根据 namespace 查找指定的 store 模块对象
        if (namespace) {
          var module = getModuleByNamespace(this.$store, 'mapState', namespace);
          if (!module) {
            return
          }
          state = module.context.state;
          getters = module.context.getters;
        }
        // 获取通过指定 namespace 得到的 store module 中的属性
        return typeof val === 'function'
          ? val.call(this, state, getters)
          : state[val]
      };
    });
    // 返回 函数对象
    return res
  });

application:

Based on this idea, the method of obtaining fields in a complex object can be optimized. The factory function defined is as follows

export const mapTargetValue = (nameSpace, keyList = [])=>{
  const result = {}
  // 注意:返回的方法不要使用箭头函数,否则拿不到 this
  // 这里 可以兼容两种形式的 keyList ,参考 mapState 中属性重命名的使用形式
  if(Array.isArray(keyList)){
    keyList.forEach( key => result[key] = function(){ 
        // 这里假设 可以直接在 this 上 获取得到 namespace对象
        // 当然 指定对象的获取复杂程度取决于 你的代码逻辑
        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
}

The usage of the defined method is exactly the same as the usage of mapState. Compared with the previous value method, the amount of repetitive code can be greatly reduced. Specific applications are as follows

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

彭博
131 声望4 粉丝

前端小白