前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >第三十七期:mapState浅析

第三十七期:mapState浅析

作者头像
terrence386
发布2022-07-15 10:13:47
4630
发布2022-07-15 10:13:47
举报
文章被收录于专栏:JavaScript高级程序设计

关于Vuex的源码,个人感觉还是很有必要去仔细研究一下的。看看别人写的代码,然后在看看自己平时写的代码,感觉完全不在一个水平上。

以Vuex源码中的mapState方法为例:

代码语言:javascript
复制
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作为参数。

代码语言:javascript
复制
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)

也就是下面的代码:

代码语言:javascript
复制
(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之类的应该与此类似。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-11-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 JavaScript高级程序设计 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档