Vuex源码学习(五)加工后的module

没有看过moduleCollection那可不行!Vuex源码学习(四)module与moduleCollectionvue

代码块和截图的区别

  1. 代码块部分但愿你们按照个人引导一行行认真的读
  2. 代码的截图是但愿你们能记住图中的结构与方法,下面会对总体进行一个分析,而不会一行一行的分析。

可是之后的文章会更偏向于使用代码块,但愿你们喜欢。vuex

上一章咱们讲述了ModuleCollection类的做用,帮助咱们把伪(未加工的)模块变成真正的模块,而后把每一个模块按照父子与兄弟关系连接起来。那么真正的模块相比于伪(未加工的)模块多了哪些能力呢?segmentfault

module提供的方法


这是module暴露出来的全部方法,以及一个属性。缓存

先看一下constructor

constructor (rawModule, runtime) {
    this.runtime = runtime
    // Store some children item
    // 建立一个容器存放该模块全部的子模块
    this._children = Object.create(null)
    // Store the origin module object which passed by programmer
    // 存放本身未被加工的模块内容。
    this._rawModule = rawModule
    const rawState = rawModule.state
    // Store the origin module‘s state
    // 建立这个模块的数据容器
    this.state = (typeof rawState === 'function' ? rawState() rawState) || {}
}

模块的初始化主要是作了如下三件事情工具

  1. 建立_children属性用于存放子模块
  2. 建立_rawModule属性存储本身模块的伪(未被加工)模块时的内容
  3. 建立state属性存储本身模块的数据内容 每一个模块都有本身的state。

模块的初始化并无作什么事情,模块提供的方法和属性才是它的核心,
模块提供了一个namespaced的属性,以及不少方法,我将模块提供的方法分红两类。学习

先说属性

get namespaced () {
    // 获取模块的namespaced属性 肯定这个模块有没有本身的命名空间
    return !!this._rawModule.namespaced
}

判断是否有命名空间有什么用?在之后设置getters、mutation、actions时有很大做用,之后再讲。this

再说方法

模块提供的全部方法都是为了给外部的调用,这些方法没有一个是让模块在本身的内部使用的。因此我把方法划分的纬度是,按照这个方法是用于构建模块树仍是用于抽取模块中的内容spa

构建模块树的方法:code

1.addChild:给模块添加子模块。对象

addChild (key, module) {
    this._children[key] = module
}

这个方法实现上很简单,它是在哪里被调用的呢?你们能够翻开上一章的moduleCollection的内容,在ModuleCollection中完成模块之间的连接,就是使用这个方法给父模块添加子模块。

  1. removeChild:移除子模块 Vuex初始化的时候未使用,但能够给你提供灵活的处理模块的能力
removeChild (key) {
    delete this._children[key]
}
  1. getChild:获取子模块 获取子模块的意义是什么?在之后配置模块的名字时,须要获取模块的是否设置了命名空间,获取命名空间的属性模块提供了,再提供一个获取子模块就都Ok了
getChild (key) {
    return this._children[key]
}
  1. updateChild:更新模块的_ra wModule属性(更新模块的未加工前的模块内容),Vuex中未使用
update (rawModule) {
    this._rawModule.namespaced = rawModule.namespaced
    if (rawModule.actions) {
      this._rawModule.actions = rawModule.actions
    }
    if (rawModule.mutations) {
      this._rawModule.mutations = rawModule.mutations
    }
    if (rawModule.getters) {
      this._rawModule.getters = rawModule.getters
    }
}

Vuex在连接与整合模块的时候使用了其中两个方法,addChild、getChild。类ModuleCollection在连接时须要找到模块(getChild)而后给模块添加子模块(addChild)的功能,因此这两个方法是在整合模块时最重要的。

抽取模块中的内容

上面的一组方法,是为了更好的完成模块的连接,给散落的单一模块整理成一个模块树能够提供便捷的封装方法,下面要说的方法什么叫作抽取模块中的内容?将这些方法暴露给外面能够方便的去获取这个模块内的一些内容来使用。


forEachValue是Vuex封装的工具方法,用于遍历对象的。

export function forEachValue (obj, fn) {
  Object.keys(obj).forEach(key => fn(obj[key], key))
}

这四个方法做用:

  1. forEachChild : 遍历模块的子模块
  2. forEachGetter : 遍历模块中_rawModule.getters 这块就应该知道 _rawModule的做用了,我把模块未加工时会有getters属性,存放这个模块全部的getters方法(vuex的基本用法就很少讲了),而后遍历,
  3. forEachMutation : 和forEachGetter相似,只是换成了遍历mutations
  4. forEachAction : 和forEachGetter相似,只是换成了遍历actions

这四个方法就是遍历这些内容,有意义吗?

意义很大,目前_rawModule上这些getters、mutations、actions属性并不会生效,只是单纯的一个属性,如何让他们能够成为那种,被dispatch、commit使用的那种方法呢?先给你们一个小提示,mutations、actions都是要被注册的,注册以前总要获取到这些内容,具体的实现方式后面的章节会详细讲述,

总结

加工后真正的module(咱们称由Module这个类实例化出来为真正的module)只是缓存了一些内容,而且给外界提供了一堆方便高效的方法。这些方便高效的方法为以后的注册action、mutation。整合state都起了很关键的做用。因此说module这个小单元为下面的代码提供了很大便利,
额外思考咱们对一段内容须要频繁的处理而且处理方式大同小异的时候,是否是能够像module同样整理成一个对象,而后给外界提供一些方法。(有一种面向对象思想)

下一章讲述action和mutation是如何调用的

我是一个应届生,最近和朋友们维护了一个公众号,内容是咱们在从应届生过渡到开发这一路所踩过的坑,已经咱们一步步学习的记录,若是感兴趣的朋友能够关注一下,一同加油~

我的公众号:咸鱼正翻身

相关文章
相关标签/搜索