看个代码代价很高,我边读边转笔,然后一个失手把手挑了个滴血不止…(笔头挑掉了一层手皮)

vuex和dva的源码都想看,不然没办法知道相性在哪。

由口而入

这都暴露干净了…

export default {
  Store,
  install,
  version: '__VERSION__',
  mapState,
  mapMutations,
  mapGetters,
  mapActions,
  createNamespacedHelpers
}

install肯定是Vue老套路,想把东西当插件用肯定要暴露这个方法。这个之前写组件经常需要碰到,弃之!

这次就先读暴露出来的四个方法吧

辅助函数

normalizeNamespace

这个东西可能要先讲,因为你看到mapState的第一眼你就会看到他,虽然不重要。

这应该是一个初始化或者标准化命名空间的方法,之前"尝试用dva的理解对处理数据"有遇到使用命名空间的情况。

computed: {
  ...mapState('spacename', {
    count: state => state.count
  })
}

看一下实现方法

function normalizeNamespace (fn) {
  return (namespace, map) => {
    if (typeof namespace !== 'string') {
      map = namespace
      namespace = ''
    } else if (namespace.charAt(namespace.length - 1) !== '/') {
      namespace += '/'
    }
    return fn(namespace, map)
  }
}

映入眼帘就是一个柯里了,大致意思就是命名空间需要处理,如果进来的函数第一个不是空间名称那么肯定直接是对象了,因为我们也不是必须使用命名空间,比如最普通的这样的

computed: {
  ...mapState({
    count: state => state.count
  })
}

如果有命名空间的话,就根据层数用/分开,比如app/save

normalizeMap

对不起还是不能讲到mapState,毕竟通用的函数理解完了之后,游戏也就结束了。(要不怎么说是辅助函数

/**
 * Normalize the map
 * normalizeMap([1, 2, 3]) => [ { key: 1, val: 1 }, { key: 2, val: 2 }, { key: 3, val: 3 } ]
 * normalizeMap({a: 1, b: 2, c: 3}) => [ { key: 'a', val: 1 }, { key: 'b', val: 2 }, { key: 'c', val: 3 } ]
 * @param {Array|Object} map
 * @return {Object}
 */
function normalizeMap (map) {
  return Array.isArray(map)
    ? map.map(key => ({ key, val: key }))
    : Object.keys(map).map(key => ({ key, val: map[key] }))
}

注释都直接告诉你了!对的实际上组件对vuex的访问可以有两种,对象或者数组。对象的情况上面已经有了,还有一种数组。

computed: {
  ...mapState('spacename', [
    'count'
  ])
}

这种是,如果组件的参数跟vuex设定一样,那么就直接传入数组匹配,相当于this.count指向this.$store.state.count

mapState, mapMutations, mapGetters, mapActions

剩下的就真的是“拼装术”的事情了,通过暴露出去的辅助函数所接收到的数据进行转换并连接vuex

相当于redux本身只提供了状态管理,便捷操作需要接触各类型插件。而vuex作为vue专属状态管理,已经提供了最适合vue的操作。

问题

由于辅助函数做的工作就是提供在组件中对vuex连接操作的工作,而函数中的转换结果都会是this.$store。在注入vue的环境中,this不出意外的话是指向vue原型上的,这也就意味着,vuex实际上也是作为插件附着在vue原型中。

不过关于这一点,在一开始就有提到,vuex是通过暴露自己的安装函数让vue可以直接use()。而且我们在main.js绑定时也默认使用store这个key。

这样的话,只要是能访问到vue的地方就可以访问到$store了,包括组件。**从而可以做到不需要什么辅助函数也不需要actions直接对状态管理动手动脚。**这不仅是react的使用者感觉到的诧异或者反感了吧。

不过团队是知道这种情况的存在的,所以他们是推荐在组件中使用辅助函数,请不要直接操作

(不过这个注释最多也就说说而已,懂道理的人都会这么做;不懂道理的,只存留“我只要解决问题就行了”的某些人是不会这么做的。)