若是你还不知道Vuex是怎么安装的,请移步Vuex源码学习(三)install都作了哪些事情前端
这一节该分析模块的是怎么被整合的,以及要整合成什么样子。vue
在Vuex的constructor中比较靠前的位置有这么两行代码,_modules属性是ModuleCollection的实例对象,以后 _modules属性被频繁使用,vue-router
这块就是对Vuex的模块进行了一次整合,整合出一个能够被使用的 _modules,而_moduleNamespaceMap是一个空对象segmentfault
先看一下咱们咱们项目中Store的结构
store/index.js
moduleList:数组
moduleSet:框架
结构就是这样的
在以上代码中的modules下的数据,我都称它是伪(未加工)模块,由于它还不具备模块的功能。
当咱们实例化Vuex.Store这个类的时候接收的参数options就会直接交给moduleCollection来处理。参数options是什么呢?就是上面图中这样结构的数据,
想要处理成什么样子?
下面看一下ModuleCollection是怎么处理的dom
export default class ModuleCollection { constructor (rawRootModule) { // register root module (Vuex.Store options) // 注册模块并连接 this.register([], rawRootModule, false) } ... register (path, rawModule, runtime = true) { if (process.env.NODE_ENV !== 'production') { // 不符合规则的模块会报错。 assertRawModule(path, rawModule) } // 建立一个模块 const newModule = new Module(rawModule, runtime) if (path.length === 0) { this.root = newModule } else { // path.slice(0,-1)就能够拿到父模块的path。 // get方法能够根据path来找到对应的模块。 const parent = this.get(path.slice(0, -1)) // 将子模块挂载到父模块上 parent.addChild(path[path.length - 1], newModule) } // register nested modules if (rawModule.modules) { // 遍历每一个模块的modules(目的是获取全部子模块) forEachValue(rawModule.modules, (rawChildModule, key) => { // 为何要path.concat(key)? // 依次注册子模块。 this.register(path.concat(key), rawChildModule, runtime) }) } } }
在Vuex与vue-router的源码中,命名变量是颇有规律的,
在开发人员使用这两个框架的时候,传递进去的参数,在使用时命名的变量名都是raw开头的,表明是未通过加工的。学习
在初始化的时候直接开始注册模块,
moduleCollection的这个类的任务是把生成的模块合理的连接起来,而模块的生成交给了Module这个类。this
因此register方法就是把根模块以及全部的子模块从一个伪(未加工)模块变成一个真正的模块而且连接起来。
遍历树形结构用什么方法? 递归!spa
register都作了什么?
递归的出口:rawModule.modules为false(模块没有子模块) ,也就是每一个模块都没有子模块须要注册了,那就表明所有加工与连接完毕。
register接收三个参数,path、rawModule、hot。
hot这个参数目前看来不关键。
rawModule是伪(未加工)模块
那path的做用是什么呢?
path的做用很大,你们类比下前端页面的dom树的Xpath,若是我想知道这个节点的位置,须要知道这个父节点的位置,而后一层一层的向上知道根结点,有了Xpath就能够直接找到这个节点,
Vuex也是同样的想知道某个模块的位置,只须要提供根结点到他的一个path,path按顺序存储着根模块到它自己的全部祖先模块(根模块没有名字,又不能把第一个放一个空,因此path里 面没有根模块),在每次注册的时候,这个模块有子模块,就把它的path加上(concat)子模块的名字,在子模块执行register方法时,path就比它的父模块多一个父模块的名字,因此根模块注册的时候传入path就是[](空数组)了。
ModuleCollection的get方法能够根据path来获取指定的模块,在挂载的时候十分有用,
,使用reduce的方法,按照数组的顺序,一层一层的找目标模块。
path对之后要讲的设置命名空间也颇有帮助。
下一章讲述生成的module具体能够作什么