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

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

由口而入

这都暴露干净了…

1
2
3
4
5
6
7
8
9
10
export default {
Store,
install,
version: '__VERSION__',
mapState,
mapMutations,
mapGetters,
mapActions,
createNamespacedHelpers
}

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

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

辅助函数

normalizeNamespace

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

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

1
2
3
4
5
computed: {
...mapState('spacename', {
count: state => state.count
})
}

看一下实现方法

1
2
3
4
5
6
7
8
9
10
11
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)
}
}

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

1
2
3
4
5
computed: {
...mapState({
count: state => state.count
})
}

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

normalizeMap

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

1
2
3
4
5
6
7
8
9
10
11
12
/**
* 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的访问可以有两种,对象或者数组。对象的情况上面已经有了,还有一种数组。

1
2
3
4
5
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的使用者感觉到的诧异或者反感了吧。

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

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