Vue.use(Vuex)
// 混入 beforeCreate 钩子
// this.$store = 传入 vue 配置的store实例
// 子组件: this.$store = parent.$store
new Vuex.Store({})
const store = new Vuex.Store({
modules: {
modules1,
modules2
},
getters,
state: {},
})
state 数据 { name, age }
mutations = {
// 同步
SET_NAME: (state, payload) => {
state.name = payload
},
}
const actions = {}
class Store
constructor(options = {}) {
// 注意几个重要属性
this._actions = {} // 所有的 action 包括子模块的
this._mutations = {} // 所有的 mutation 包括子模块的
this._wrappedGetters = {} // 所有的 getter 包括子模块的
// this 是 store 实例
// this._modules 是 ModuleCollection 实例
// this._modules.root 是 Module 实例
this._modules = new ModuleCollection(options)
// this._modules.root = Module // 根模块 module 实例
// 看一下 Module 实例的属性
{
_children: {} // 子 module 实例
state: 自身模块的state
_rawModule
namespace
}
}
installModule(this, state, [], this._modules.root)
{
const namespace = store._modules.getNamespace(path) // 得到模块 namespace
parentState[moduleName] = module.state // 子模块的 state 都放在 rootState 上
const local = module.context = makeLocalContext(store, namespace, path)
// module.context
{
dispatch: noNamespace ? store.dispatch : (type, payload) => {
// 到时候就从 this._actions 中找
return store.dispatch(namespace + type, payload)
}
commit: noNamespace ? store.commit : (type, payload, options) => {
store.commit(namespace + type, payload, options)
}
getters: {
get: noNamespace
? () => store.getters
: () => makeLocalGetters(store, namespace)
}
// 子模块的state
state: {
get: () => getNestedState(store.state, path)
}
}
将每个模块的 actions mutations getters 经过包装放在store实例上
// mutations
store._mutations[namespace + key] = [
function wrappedMutationHandler (payload) {
// handler 其实就是模块mutations中key对应的函数(用户指定)
handler.call(store, local.state/* 模块自身的state */, payload)
}
]
// actions
store._actions = {
'namespace/actionName': function wrappedActionHandler (payload) {
// handler 其实就是模块actions中key对应的函数(用户指定)
let res = handler.call(store, {
dispatch: local.dispatch, // (type, payload) => store.dispatch(namespace + type, payload)
commit: local.commit, // 同上
getters: local.getters, // { key: store.getters[namespace + key] }
state: local.state,
rootGetters: store.getters,
rootState: store.state
}, payload)
// 异步处理
if (!isPromise(res)) {
res = Promise.resolve(res)
}
return res
}
}
// getters
store._wrappedGetters = {
key: function wrappedGetter (store) {
return rawGetter( // 实际定义的getter函数(用户指定)
local.state, // local state
local.getters, // local getters
store.state, // root state
store.getters // root getters
)
}
}
}
resetStoreState
store.getters = {}
const wrappedGetters = store._wrappedGetters
const computedObj = {}
computedObj[key] = partial(fn, store)
// 你可以把 getters 理解成 state 的计算属性,这里state属性收集了 getters 的watcher
computedCache[key] = computed(() => computedObj[key]())
Object.defineProperty(store.getters, key, {
get: () => computedCache[key].value, // 缓存效果
enumerable: true,
})
// state 做响应式处理,组件调用属性的时候收集了组件的渲染watcher,通过 commit 执行改变state,触发重新渲染
store._state = reactive({
data: state
})