关于Vuex的源码,个人感觉还是很有必要去仔细研究一下的。看看别人写的代码,然后在看看自己平时写的代码,感觉完全不在一个水平上。
以Vuex源码中的mapState
方法为例:
export const mapState = normalizeNamespace((namespace, states) => {
const res = {}
if (__DEV__ && !isValidMap(states)) {
console.error('[vuex] mapState: mapper parameter must be either an Array or an Object')
}
normalizeMap(states).forEach(({ key, val }) => {
res[key] = function mappedState () {
let state = this.$store.state
let getters = this.$store.getters
if (namespace) {
const 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
})
它这里用到了normalizeNamespace
方法。这个方法的作用是返回一个函数,接受namespace和map作为参数。
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)
}
}
然后mapState
方法其实就等于normalizeNamespace
方法最后返回的fn(namespace, map)
。
也就是下面的代码:
(namespace, states) => {
const res = {}
if (__DEV__ && !isValidMap(states)) {
console.error('[vuex] mapState: mapper parameter must be either an Array or an Object')
}
normalizeMap(states).forEach(({ key, val }) => {
res[key] = function mappedState () {
let state = this.$store.state
let getters = this.$store.getters
if (namespace) {
const 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
}
这函数会先将参数中的states
转化为正常化的Map,然后进行遍历,重新定义了res对象,将遍历Map的key值对应的value赋给res对象,最后这个函数返回了res对象。
不考虑中间调用call的过程,单单是mapState等于一个函数,函数最后又返回一个对象的操作,这么连起来写的过程,好像我自己也很少这么写。
自己写的话,最多也就把一些常用的,或者用的地方比较多的方法抽成一个方法,有可能接收不同的参数,然后返回不同的值,并且也很少用到call这个方法。
mapState说白了还是一个函数,这个函数会遍历由state对象转化成的Map,然后重新组合成一个新的对象进行返回,只不过在重新组合的时候会判断每个建对应的值是不是函数,如果是函数,则将该键的值更新为函数执行后的值。
依次看来,mapActions,mapMutations之类的应该与此类似。
本文分享自 JavaScript高级程序设计 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!