看个代码代价很高,我边读边转笔,然后一个失手把手挑了个滴血不止…(笔头挑掉了一层手皮)
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的使用者感觉到的诧异或者反感了吧。
不过团队是知道这种情况的存在的,所以他们是推荐在组件中使用辅助函数,请不要直接操作。
(不过这个注释最多也就说说而已,懂道理的人都会这么做;不懂道理的,只存留“我只要解决问题就行了”的某些人是不会这么做的。)