Vuex之module的register实现

Vuex源码中module的register方法

register 翻译为登记 ,可以理解为 每一个module都进行登记
Vuex中的源码module-collection中两个方法

class ModuleCollection {
    // rawRootModule 为 Vue的 options属性
    constructor (rawRootModule) {
        // register root module (Vuex.Store options)
        this.register([], rawRootModule, false)
    }
    get (path) {
        return path.reduce((module, key) => {
          return module.getChild(key)
        }, this.root)
    }
    // path 为空数组 []   rawModule 为传入的options
    register (path, rawModule, runtime = true) {
        /*
            Module创建对象主要参数为  子元素 module模块中内容 状态
            this._children = Object.create(null) 
            this._rawModule = rawModule 
            const rawState = rawModule.state
        */
        const newModule = new Module(rawModule, runtime)
        if (path.length === 0) {
            this.root = newModule
        } else {
          const parent = this.get(path.slice(0, -1))
          parent.addChild(path[path.length - 1], newModule)
        }

        // register nested modules
        if (rawModule.modules) {
          forEachValue(rawModule.modules, (rawChildModule, key) => {
            this.register(path.concat(key), rawChildModule, runtime)
          })
        }
    }
}

模拟实现

let obj = {
    module:{
        a:{
            state:{
                a:"a"
            },
            module:{
                c:{
                    state:"c",
                }
            }
        },
        b:{
            state:{
                b:"b"
            }
        }
    },
    state:{
        root:"123"
    }
}
/*
    改为 格式
    let root = {
        // 也就是 options
        _raw:rootModule, 
        // 状态
        state:{},
        // 子module
        _children:{}
    }
*/
class ModuleCollect{
    constructor(options) {
        // 开始创建为指定格式
        // 参数1 为属性名数组对象
        this.register([],options);
    }
    // 接收 属性名数组,和对应的option 参数列表
    register(moduleNameList,moduleOptions){
        let newModule = {
            _raw:moduleOptions,
            state:moduleOptions.state,
            _children:{}
        }
        // 判断list身上是否是空的 如果是空的就让根module为newModule
        if(moduleNameList.length === 0){
            this.root = newModule;
        }else{
            // 查找对应父属性 ,在父属性中每一个子属性改为 newModule 样式
            let parent = moduleNameList.slice(0,-1).reduce((root,current)=>{
                // 返回moduleNameList中 倒数第二个元素的属性
                // 使用reduce递归去找 找到倒数第二个元素
                return root._children[current];
            },this.root)
            // 父元素的children数组里面的最后一个元素 为newModule
            parent._children[moduleNameList[moduleNameList.length-1]] = newModule;
        }
        if(moduleOptions.module){
            Object.keys(moduleOptions.module).forEach((item)=>{ // item 分别为 a,c,b
                // 递归调用
                // moduleNameList 分别为 item为a时 [],item为c时 [a],item为b时 []
                // moduleNameList.concat(item)  [a]        [a,c]        [b]
                this.register(moduleNameList.concat(item),moduleOptions.module[item]);
            })
        }
    }
}
console.log(new ModuleCollect(obj))

register的原理 就是将传递的不规则参数,改为指定格式用于后续用途 Vuex中大多数使用该种递归方式实现递归

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 上一章总结了 Vuex 的框架原理,这一章我们将从 Vuex 的入口文件开始,分步骤阅读和解析源码。由于 Vuex...
    你的肖同学阅读 5,768评论 3 16
  • 前言 之前几篇解析 Vue 源码的文章都是完整的分析整个源码的执行过程,这篇文章我会将重点放在核心原理的解析,不会...
    心_c2a2阅读 5,327评论 1 8
  • Vuex源码阅读分析 Vuex是专为Vue开发的统一状态管理工具。当我们的项目不是很复杂时,一些交互可以通过全局事...
    steinslin阅读 3,793评论 0 6
  • 这几天忙啊,有绝地求生要上分,英雄联盟新赛季需要上分,就懒着什么也没写,很惭愧。这个vuex,vue-router...
    公子世无双ss阅读 3,843评论 0 0
  • 写在前面 因为对Vue.js很感兴趣,而且平时工作的技术栈也是Vue.js,这几个月花了些时间研究学习了一下Vue...
    染陌同学阅读 5,564评论 0 12