Appearance
Getter
使用方式
js
moduleABA.getters: {
// ...
doneTodosCount (state, getters) {
return getters.doneTodos.length
}
}
store.getters["moduleA/modueleAB/modueleABA/getters"] // -> 1
初始化阶段
遍历处理 module 中的 getters 属性,将每一个 getter 按照以其 namespaced + / + getterNameKey
为 key 存储到 store._wrappedGetters[type]
下。这样上面moduleA/modueleAB/modueleABA/getters
就会变成 store._wrappedGetters["moduleA/modueleAB/modueleABA/getters"] = () => {}
这边根 action 一样两组不同的对象 local.state
store.state
js
/**
* 在store上注册当前getter方法
* @param {*} store 根store
* @param {*} type namespace
* @param {*} rawGetter getter回调方法
* @param {*} local local context对象
* @returns
*/
function registerGetter(store, type, rawGetter, local) {
// 如果已存在,则报重复
if (store._wrappedGetters[type]) {
if (process.env.NODE_ENV !== "production") {
console.error(`[vuex] duplicate getter key: ${type}`)
}
return
}
store._wrappedGetters[type] = function wrappedGetter(store) {
// 执行回调方法,入参为 local.state local.getters store.state store.getters
return rawGetter(
local.state, // local state
local.getters, // local getters
store.state, // root state
store.getters // root getters
)
}
}
getter 的访问
访问方式为 store.getters["moduleA/modueleAB/modueleABA/getters"] // -> 1
, 其实现方法在 resetStoreVM 方法中
核心源码为:
js
function resetStoreVM(store, state, hot) {
// bind store public getters
store.getters = {}
const wrappedGetters = store._wrappedGetters
const computed = {}
forEachValue(wrappedGetters, (fn, key) => {
// use computed to leverage its lazy-caching mechanism
computed[key] = () => fn(store)
// 将 store._wrappedGetters 的所有属性 代理到 store.getters上
Object.defineProperty(store.getters, key, {
get: () => store._vm[key],
enumerable: true, // for local getters
})
})
// 生成一个空的Vue实例,然后将所有的getters的属性 作为计算属性 存放在 _vm上
store._vm = new Vue({
data: {
$$state: state,
},
computed,
})
}
可见其也是借助于 Vue 的计算属性功能 将store.getters["moduleA/modueleAB/modueleABA/getters"]
代理到 store._vm["moduleA/modueleAB/modueleABA/getters"]
,这样就可以使得当 state 发生变化的时候响应式触发 computed 中 getter 方法的回调
总结
其不是按照树结构存储在 store 下的,而是按照命令空间扁平化的方式通过 getNamespace() 方法生成其唯一的字符串 key 存储在
store._wrappedGetters
下借助于 Vue 响应式功能将 store 的 getter 注册到 computed 属性下,从而实现 state 的跟新触发 getter 的回调功能