模块收集
- vuex/module/module-collection.js
import { forEach } from '../util' import Module from './module'; class ModuleCollection { constructor(options) { // 对数据进行格式化操作 // this.root = { // _raw: '用户定义的模块', // state: '当前模块自己的状态', // _children: { // 孩子列表 // a: { // _raw: '用户定义的模块', // state: '当前模块自己的状态', // _children: { // 孩子列表 // e: {} // } // }, // c: { // } // } // } this.root = null; this.register([], options); // 创建一个栈结构,为了记录父子关系(上一级为下一级的父亲) } register(path, rawModule) { let newModule = new Module(rawModule) rawModule.newModule = newModule; // 自定义属性 if (path.length == 0) { this.root = newModule } else { // 找父亲:从根节点依次向下查找 let parent = path.slice(0, -1).reduce((memo, current) => { return memo.getChild(current) }, this.root); parent.addChild(path[path.length - 1], newModule); // 根据当前注册的key ,将他注册到对应的模块的儿子处 } // 注册完毕当前模块,在进行注册根模块 // 用户进行了 modules 模块化操作 if (rawModule.modules) { forEach(rawModule.modules, (module, key) => { // 递归遍历,将 modules 格式化成上述的树形结构 // 此处 path.concat(key) 会返回一个新 [],不会存在引用问题(此处是深度优先遍历) this.register(path.concat(key), module); }) } } } export default ModuleCollection
- vuex/module/module.js
import { forEach } from '../util' class Module { constructor(rawModule) { this._raw = rawModule; this._children = {}; this.state = rawModule.state // { // _raw:rootModule, // _children:{}, // state:rootModule.state // } } getChild(childName) { return this._children[childName] } addChild(childName, module) { this._children[childName] = module } forEachGetter(cb) { this._raw.getters && forEach(this._raw.getters, cb) } forEachMutation(cb) { this._raw.mutations && forEach(this._raw.mutations, cb) } forEachAction(cb) { this._raw.actions && forEach(this._raw.actions, cb) } forEachChildren(cb) { this._children && forEach(this._children, cb) } // 用于标识他自己是否写了 namesapced get namespaced() { // module.namespaced return !!this._raw.namespaced; } } export default Module
模块安装、模块实现
import { Vue } from './install'
import ModuleCollection from './module/module-collection';
import { forEach } from './util';
function installModule(store, rootState, path, module) { // a/b/c/d
// 需要循环当前模块的
// module.state => 放到rootState对应的儿子里
if (path.length > 0) { // 儿子模块
// 需要找到对应父模块,将状态声明上去
// {name:'zf',age:'12',a:aState}
let parent = path.slice(0, -1).reduce((memo, current) => {
return memo[current];
}, rootState);
// 对象新增属性不能导致重新更新视图
Vue.set(parent, path[path.length - 1], module.state);
}
module.forEachGetter((fn, key) => {
store.wrapperGetters[key] = function () {
return fn.call(store, module.state);
}
});
module.forEachMutation((fn, key) => { // {myAge:[fn,fn]}
store.mutations[key] = store.mutations[key] || [];
store.mutations[key].push((payload) => {
return fn.call(store, module.state, payload)
})
});
module.forEachAction((fn, key) => {
store.actions[key] = store.actions[key] || [];
store.actions[key].push((payload) => {
return fn.call(store, store, payload)
})
});
module.forEachChildren((child, key) => {
installModule(store, rootState, path.concat(key), child);
});
}
class Store {
constructor(options) {
// 对用户的模块进行整合
// 当前格式化完毕的数据 放到了this._modules里
this._modules = new ModuleCollection(options); // 对用户的参数进行格式化操作
this.wrapperGetters = {}
this.getters = {}; // 我需要将模块中的所有的getters,mutations,actions进行收集
this.mutations = {};
this.actions = {};
const computed = {};
// 没有namespace的时候 getters都放在根上 ,actions,mutations 会被合并数组
let state = options.state;
installModule(this, state, [], this._modules.root);
forEach(this.wrapperGetters, (getter, key) => {
computed[key] = getter;
Object.defineProperty(this.getters, key, {
get: () => this._vm[key]
})
});
this._vm = new Vue({
data: {
$$state: state
},
computed
});
console.log(this.getters, this.mutations, this.actions)
}
get state() {
return this._vm._data.$$state
}
commit = (mutationName, payload) => { // 发布
this.mutations[mutationName] && this.mutations[mutationName].forEach(fn => fn(payload))
}
dispatch = (actionName, payload) => {
this.actions[actionName] && this.actions[actionName].forEach(fn => fn(payload))
}
}
// state getters action mutation (modules 分层)
export default Store;
打赏作者
您的打赏是我前进的动力
微信
支付宝
vuex 中的初始化
上一篇
评论