很多同学应该都知道mapState有以下三种写法:
不知道的童鞋可以查看本博客的《vuex的mapState mapActions mapMutations mapGetters在模块module使用详解》

export default {
  computed: {
        ...mapState('pim', {
            count: state => state.count, // 1
            page: 'currentPage', // 2
          }),
        ...mapState('pim', ['total']) // 3
}

它是怎么实现的呢?让人用起来很灵活啊。
先看看mapState的源码

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;
      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(this, state, getters)
        : state[val]
    };
    // mark vuex getter for devtools
    res[key].vuex = true;
  });
  return res
});

里面主要做数据归一化的是normalizeMap方法

function normalizeMap (map) {
  return Array.isArray(map)
    ? map.map(function (key) { return ({ key: key, val: key }); })
    : Object.keys(map).map(function (key) { return ({ key: key, val: map[key] }); })
}

最终不会是数组还是对象的参数转为类似下面的数组

[{
    key: 'count',
    val: (state) => state.count
},{
    key: 'page',
    val: 'currentPage'
},{
    key: 'total',
    val: 'total'
}]

然后我们就可以按照数组来处理了,所以源码里面可以直接用forEach了。
具体mapState的使用及源码分析就不讲了,《vuex的mapState mapActions mapMutations mapGetters在模块module使用详解》里面介绍的很详情。

我们这里要学习的是这种写法,通过数据归一化normalize实现自己封装的方法也能支持多种参数,它带来了下列好处:

  1. 让用户使用的时候感觉很爽,支持比较灵活的传参方式
    2.自己在封装方法时后续代码的不用动不动就判断传参是对象还是数组,使得代码的可维护性更强

这里我想强调一下的是在数据归一化的时候不要失真,比如这里我们可以把数组参数['count']变成对象参数{key: 'count', val: 'count'},而不是反过来,不然{page: 'currentPage'}怎么办,变成['page']?这样就失真了啊,缺失了currentPage了,虽然你在入参传入的对象里面根据page的key还是能拿到currentPage这个value的,但是这样写法就不优雅,耦合性较强了。


发表评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据