Skip to content

Instantly share code, notes, and snippets.

@chearon
Created August 20, 2018 20:12
Show Gist options
  • Save chearon/fadb7fad364e858e84257d1c4703f568 to your computer and use it in GitHub Desktop.
Save chearon/fadb7fad364e858e84257d1c4703f568 to your computer and use it in GitHub Desktop.
Nested getters in Vuex
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