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中大多數使用該種遞歸方式實現遞歸

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章