道招

vuex的mapState mapActions mapMutations mapGetters在模块module使用详解

如果您发现本文排版有问题,可以先点击下面的链接切换至老版进行查看!!!

vuex的mapState mapActions mapMutations mapGetters在模块module使用详解

我们使用主要是为了简洁自己的代码, 没用这些方法之前我们的代码可能是这样的(这里用使用了modules的来举例子,没有module的使用更简单,这里的module为pim),mutation和action的使用方式一致就不单独举例子了。
export default {
    computed: {
        count(){
            return this.$store.state.pim.count;
        },
        newCount(){
            return this.$store.getters['pim/newCount'];
        }
    },
    methods: {
        getList(params){
            return this.$store.dispatch('pim/getList', params);
        }
    }
}
使用了mapState mapActions mapMutations mapGetters代码会显得简单很多
import {mapState, mapActions, mapMutations, mapGetters}
export default {
    computed: {
        ...mapState('pim', {
            count: state => state.count
        }),
        ...mapGetters('pim', ['newCount'],
    },
    methods: {
        ...mapActions('pim', ['getList']),
    }
}
是不是简洁多了 但是有个问题 看mapState很容易看出我们是把 pim的state里面的count映射成当前this下面的count,所以我们也可以将它映射成count2。但是mapGetters、mapActions、mapMutations怎么办,直接一个[]是很爽,哈哈。 但是如果pim的store里面的命名跟我当前vue实例里面的重复了呢?比如我想把actions里面的getList映射成vue实例里面的fetchList方法,而不是也叫getList呢 对于mapActions官网是这么讲的。
...mapActions([
    'some/nested/module/foo', // -> this['some/nested/module/foo']()
    'some/nested/module/bar' // -> this['some/nested/module/bar']()
])
或者
...mapActions('some/nested/module', [
    'foo', // -> this.foo()
    'bar' // -> this.bar()
])
一般情况下使用是够用的,但是对于我们解决上面提到的命名重复的问题还是没有帮助。。。 很多网上介绍mapState mapActions mapMutations mapGetters的文章也有意无意的没有讲。 我们就只能看看vuex里面的源码了,看看mapActions这些方法是怎么解析传参的。
var mapActions = normalizeNamespace(function (namespace, actions) {
  var res = {};
  normalizeMap(actions).forEach(function (ref) {
    var key = ref.key;
    var val = ref.val;

    res[key] = function mappedAction () {
      var args = [], len = arguments.length;
      while ( len-- ) args[ len ] = arguments[ len ];

      var dispatch = this.$store.dispatch;
      if (namespace) {
        var module = getModuleByNamespace(this.$store, 'mapActions', namespace);
        if (!module) {
          return
        }
        dispatch = module.context.dispatch;
      }
      return typeof val === 'function'
        ? val.apply(this, [dispatch].concat(args))
        : dispatch.apply(this.$store, [val].concat(args))
    };
  });
  return res
});
在mapActions(mapState mapMutations mapGetters类似)一开始会调用一个叫normalizeMap的方法。 我们接着看看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] }); })
}
原来就是它在处理我们传入的第二个参数['getList']normalizeMap会把入参转化成装着{key: 'getList', val: 'getList'}的数组,我们可以看到如果传入的不是数组的话,normalizeMap会把入参当做对象来处理,依然把对象转化为{key: xxx, val: ***}的形式,最后已数组返回,所以要解决上面的问题我们在mapActions的第二个参数传入一个对象就行了,我们已经离成功很近了,现在有个小问题,这个对象的key是getList还是fetchList呢??? 这是我们就得回到mapActions的源代码了,看看最终执行的是key还是val了?
return typeof val === 'function'
        ? val.apply(this, [dispatch].concat(args))
        : dispatch.apply(this.$store, [val].concat(args))
真正执行的actions的是根据val,所以我们的问题有答案了
methods: {
        ...mapActions('pim', {
            fetchList: 'getList'
        }),
}
这样我们就把actions里面的getList映射成了vue实例里面的fetchList方法了。 细心的童鞋应该发现了typeof val === 'function',所以我们还可以这样用
methods: {
        ...mapActions('pim', {
            fetchList(dispatch, params){
                dispatch('getList', params);
            }
        }),
}
这样也是把getList映射成了fetchList方法了。 相信这次应该讲的很详细了吧,希望对大家有用。
更新时间:
上一篇:用webpack的require.context() 简化你的代码下一篇:webpack反向代理proxyTable设置

相关文章

从mapState、mapMutations的源码看数据归一化normalize

很多同学应该都知道 mapState 有以下三种写法: 不知道的童鞋可以查看本博客的 《vuex的mapState mapActions mapMutations mapGetters在模块modu 阅读更多…

vue单元测试vuex,mutation,尤其是actions、getters怎么测?让你像使用vuex一样测试vuex

vuex 怎么单元测试,我们只能通过检验state的值是否符合预期来测试,所以,正常的套路应该是测试mutation,然后看看对应的state是否发生了符合预期的变化。没错。 mutation 阅读更多…

关注道招网公众帐号
道招开发者二群