Created
August 20, 2018 20:12
-
-
Save chearon/fadb7fad364e858e84257d1c4703f568 to your computer and use it in GitHub Desktop.
Nested getters in Vuex
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/store.js b/src/store.js | |
index b5b083c..e5686f4 100644 | |
--- a/src/store.js | |
+++ b/src/store.js | |
@@ -222,21 +222,37 @@ function resetStore (store, hot) { | |
resetStoreVM(store, state, hot) | |
} | |
+function registerModuleGetters (store, getters, path, module, computed) { | |
+ module.forEachGetter((_getter, key) => { | |
+ const computedKey = store._modules.getNamespace(path) + key | |
+ const getter = store._wrappedGetters[computedKey] | |
+ const descriptor = { | |
+ get: () => store._vm[computedKey], | |
+ enumerable: true // for local getters | |
+ } | |
+ | |
+ Object.defineProperty(getters, key, descriptor) | |
+ Object.defineProperty(store.rootGetters, computedKey, descriptor) | |
+ | |
+ computed[computedKey] = () => getter(store) | |
+ }) | |
+ | |
+ module.forEachChild((child, key) => { | |
+ const childGetters = getters[key] = {} | |
+ registerModuleGetters(store, childGetters, path.concat(key), child, computed) | |
+ }) | |
+ | |
+ return computed | |
+} | |
+ | |
function resetStoreVM (store, state, hot) { | |
const oldVm = store._vm | |
// bind store public getters | |
- store.getters = {} | |
- const wrappedGetters = store._wrappedGetters | |
+ const getters = store.getters = {} | |
const computed = {} | |
- forEachValue(wrappedGetters, (fn, key) => { | |
- // use computed to leverage its lazy-caching mechanism | |
- computed[key] = () => fn(store) | |
- Object.defineProperty(store.getters, key, { | |
- get: () => store._vm[key], | |
- enumerable: true // for local getters | |
- }) | |
- }) | |
+ store.rootGetters = {} | |
+ registerModuleGetters(store, getters, [], store._modules.root, computed) | |
// use a Vue instance to store the state tree | |
// suppress warnings just in case the user has added | |
@@ -355,7 +371,7 @@ function makeLocalContext (store, namespace, path) { | |
Object.defineProperties(local, { | |
getters: { | |
get: noNamespace | |
- ? () => store.getters | |
+ ? () => store.rootGetters | |
: () => makeLocalGetters(store, namespace) | |
}, | |
state: { | |
@@ -370,7 +386,7 @@ function makeLocalGetters (store, namespace) { | |
const gettersProxy = {} | |
const splitPos = namespace.length | |
- Object.keys(store.getters).forEach(type => { | |
+ Object.keys(store.rootGetters).forEach(type => { | |
// skip if the target getter is not match this namespace | |
if (type.slice(0, splitPos) !== namespace) return | |
@@ -381,7 +397,7 @@ function makeLocalGetters (store, namespace) { | |
// Define as getter property because | |
// we do not want to evaluate the getters in this time. | |
Object.defineProperty(gettersProxy, localType, { | |
- get: () => store.getters[type], | |
+ get: () => store.rootGetters[type], | |
enumerable: true | |
}) | |
}) | |
@@ -404,7 +420,7 @@ function registerAction (store, type, handler, local) { | |
commit: local.commit, | |
getters: local.getters, | |
state: local.state, | |
- rootGetters: store.getters, | |
+ rootGetters: store.rootGetters, | |
rootState: store.state | |
}, payload, cb) | |
if (!isPromise(res)) { | |
@@ -433,7 +449,7 @@ function registerGetter (store, type, rawGetter, local) { | |
local.state, // local state | |
local.getters, // local getters | |
store.state, // root state | |
- store.getters // root getters | |
+ store.rootGetters // root getters | |
) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment