Skip to content

Commit d3ddc02

Browse files
committed
Implemented getters into the store.
Passing the stores state to the getters. The getters get combined.
1 parent adaa2c3 commit d3ddc02

File tree

3 files changed

+91
-10
lines changed

3 files changed

+91
-10
lines changed

src/index.js

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createAction, mergeObjects, deepClone } from './util'
1+
import { createAction, validateHotModules, mergeObjects, deepClone } from './util'
22
import devtoolMiddleware from './middlewares/devtool'
33
import createLogger from './middlewares/logger'
44

@@ -20,6 +20,7 @@ export class Store {
2020
actions = {},
2121
mutations = {},
2222
middlewares = [],
23+
getters = {},
2324
strict = false
2425
} = {}) {
2526
// bind dispatch to self
@@ -33,9 +34,11 @@ export class Store {
3334
})
3435
this._dispatching = false
3536
this.actions = Object.create(null)
37+
this.getters = Object.create(null)
3638
this._setupActions(actions)
3739
this._setupMutations(mutations)
3840
this._setupMiddlewares(middlewares, state)
41+
this._setupGetters(getters)
3942
// add extra warnings in strict mode
4043
if (strict) {
4144
this._setupMutationCheck()
@@ -104,13 +107,16 @@ export class Store {
104107
* - {Object} [mutations]
105108
*/
106109

107-
hotUpdate ({ actions, mutations } = {}) {
110+
hotUpdate ({ actions, mutations, getters } = {}) {
108111
if (actions) {
109112
this._setupActions(actions, true)
110113
}
111114
if (mutations) {
112115
this._setupMutations(mutations)
113116
}
117+
if (getters) {
118+
this._setupGetters(getters, true)
119+
}
114120
}
115121

116122
/**
@@ -163,13 +169,34 @@ export class Store {
163169
})
164170
// delete public actions that are no longer present
165171
// after a hot reload
166-
if (hot) {
167-
Object.keys(this.actions).forEach(name => {
168-
if (!actions[name]) {
169-
delete this.actions[name]
170-
}
171-
})
172-
}
172+
if (hot) validateHotModules(this.actions, actions)
173+
}
174+
175+
/**
176+
* Set up the callable getter functions exposed to components.
177+
* This method can be called multiple times for hot updates.
178+
* We keep the real getter functions in an internal object,
179+
* and expose the public object which are just wrapper
180+
* functions that point to the real ones. This is so that
181+
* the reals ones can be hot reloaded.
182+
*
183+
* @param {Object} getters
184+
* @param {Boolean} [hot]
185+
*/
186+
_setupGetters (getters, hot) {
187+
this._getters = Object.create(null)
188+
getters = Array.isArray(getters)
189+
? mergeObjects(getters)
190+
: getters
191+
Object.keys(getters).forEach(name => {
192+
this._getters[name] = (...payload) => getters[name](this.state, ...payload)
193+
if (!this.getters[name]) {
194+
this.getters[name] = (...args) => this._getters[name](...args)
195+
}
196+
})
197+
// delete public getters that are no longer present
198+
// after a hot reload
199+
if (hot) validateHotModules(this.getters, getters)
173200
}
174201

175202
/**

src/util.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,22 @@ export function createAction (action, store) {
1616
}
1717
}
1818

19+
/**
20+
* Validates hot api - unassigns any methods
21+
* that do not exist.
22+
*
23+
* @param {Object} currentMethods
24+
* @param {Object} newMethods
25+
*/
26+
27+
export function validateHotModules (currentMethods, newMethods) {
28+
Object.keys(currentMethods).forEach(name => {
29+
if (!newMethods[name]) {
30+
delete currentMethods[name]
31+
}
32+
})
33+
}
34+
1935
/**
2036
* Merge an array of objects into one.
2137
*

test/test.js

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ describe('Vuex', () => {
3131
actions: {
3232
test: TEST
3333
},
34+
getters: {
35+
getA (state) {
36+
return state.a
37+
}
38+
},
3439
mutations: {
3540
[TEST] (state, n) {
3641
state.a += n
@@ -39,6 +44,7 @@ describe('Vuex', () => {
3944
})
4045
store.actions.test(2)
4146
expect(store.state.a).to.equal(3)
47+
expect(store.getters.getA()).to.equal(3)
4248
})
4349

4450
it('async action', function (done) {
@@ -92,20 +98,40 @@ describe('Vuex', () => {
9298
state.c += n
9399
}
94100
}
101+
],
102+
getters: [
103+
{
104+
getA (state) {
105+
return state.a
106+
}
107+
},
108+
{
109+
getB (state) {
110+
return state.b
111+
},
112+
113+
getC (state) {
114+
return state.c
115+
}
116+
}
95117
]
96118
})
97119
store.actions.test(2)
98120
expect(store.state.a).to.equal(3)
99121
expect(store.state.b).to.equal(3)
100122
expect(store.state.c).to.equal(1)
123+
expect(store.getters.getA()).to.equal(3)
124+
expect(store.getters.getB()).to.equal(3)
125+
expect(store.getters.getC()).to.equal(1)
101126
store.actions.test2(2)
102127
expect(store.state.c).to.equal(3)
103128
})
104129

105130
it('hot reload', function () {
106131
const store = new Vuex.Store({
107132
state: {
108-
a: 1
133+
a: 1,
134+
b: 2
109135
},
110136
actions: {
111137
test: TEST
@@ -114,11 +140,17 @@ describe('Vuex', () => {
114140
[TEST] (state, n) {
115141
state.a += n
116142
}
143+
},
144+
getters: {
145+
getA (state) {
146+
return state.b
147+
}
117148
}
118149
})
119150
const test = store.actions.test
120151
test(2)
121152
expect(store.state.a).to.equal(3)
153+
expect(store.getters.getA()).to.equal(2)
122154
store.hotUpdate({
123155
actions: {
124156
test: ({ dispatch }, n) => dispatch(TEST, n + 1)
@@ -127,10 +159,16 @@ describe('Vuex', () => {
127159
[TEST] (state, n) {
128160
state.a = n
129161
}
162+
},
163+
getters: {
164+
getA (state) {
165+
return state.a
166+
}
130167
}
131168
})
132169
test(999)
133170
expect(store.state.a).to.equal(1000)
171+
expect(store.getters.getA()).to.equal(1000)
134172
})
135173

136174
it('middleware', function () {

0 commit comments

Comments
 (0)