1
- import { createAction , validateHotModules , mergeObjects , deepClone } from './util'
1
+ import { mergeObjects , deepClone } from './util'
2
2
import devtoolMiddleware from './middlewares/devtool'
3
3
import createLogger from './middlewares/logger'
4
+ import override from './override'
4
5
5
6
let Vue
6
7
@@ -17,12 +18,14 @@ export class Store {
17
18
18
19
constructor ( {
19
20
state = { } ,
20
- actions = { } ,
21
21
mutations = { } ,
22
+ modules = { } ,
22
23
middlewares = [ ] ,
23
- getters = { } ,
24
24
strict = false
25
25
} = { } ) {
26
+ this . _dispatching = false
27
+ this . _rootMutations = this . _mutations = mutations
28
+ this . _modules = modules
26
29
// bind dispatch to self
27
30
const dispatch = this . dispatch
28
31
this . dispatch = ( ...args ) => {
@@ -32,13 +35,9 @@ export class Store {
32
35
this . _vm = new Vue ( {
33
36
data : state
34
37
} )
35
- this . _dispatching = false
36
- this . actions = Object . create ( null )
37
- this . getters = Object . create ( null )
38
- this . _setupActions ( actions )
39
- this . _setupMutations ( mutations )
38
+ this . _setupModuleState ( state , modules )
39
+ this . _setupModuleMutations ( modules )
40
40
this . _setupMiddlewares ( middlewares , state )
41
- this . _setupGetters ( getters )
42
41
// add extra warnings in strict mode
43
42
if ( strict ) {
44
43
this . _setupMutationCheck ( )
@@ -103,20 +102,53 @@ export class Store {
103
102
* Hot update actions and mutations.
104
103
*
105
104
* @param {Object } options
106
- * - {Object} [actions]
107
105
* - {Object} [mutations]
106
+ * - {Object} [modules]
108
107
*/
109
108
110
- hotUpdate ( { actions, mutations, getters } = { } ) {
111
- if ( actions ) {
112
- this . _setupActions ( actions , true )
113
- }
114
- if ( mutations ) {
115
- this . _setupMutations ( mutations )
116
- }
117
- if ( getters ) {
118
- this . _setupGetters ( getters , true )
119
- }
109
+ hotUpdate ( { mutations, modules } = { } ) {
110
+ this . _rootMutations = this . _mutations = mutations || this . _rootMutations
111
+ this . _setupModuleMutations ( modules || this . _modules )
112
+ }
113
+
114
+ /**
115
+ * Attach sub state tree of each module to the root tree.
116
+ *
117
+ * @param {Object } state
118
+ * @param {Object } modules
119
+ */
120
+
121
+ _setupModuleState ( state , modules ) {
122
+ const { setPath } = Vue . parsers . path
123
+ Object . keys ( modules ) . forEach ( key => {
124
+ setPath ( state , key , modules [ key ] . state )
125
+ } )
126
+ }
127
+
128
+ /**
129
+ * Bind mutations for each module to its sub tree and
130
+ * merge them all into one final mutations map.
131
+ *
132
+ * @param {Object } modules
133
+ */
134
+
135
+ _setupModuleMutations ( modules ) {
136
+ this . _modules = modules
137
+ const { getPath } = Vue . parsers . path
138
+ const allMutations = [ this . _rootMutations ]
139
+ Object . keys ( modules ) . forEach ( key => {
140
+ const module = modules [ key ]
141
+ // bind mutations to sub state tree
142
+ const mutations = { }
143
+ Object . keys ( module . mutations ) . forEach ( name => {
144
+ const original = module . mutations [ name ]
145
+ mutations [ name ] = ( state , ...args ) => {
146
+ original ( getPath ( state , key ) , ...args )
147
+ }
148
+ } )
149
+ allMutations . push ( mutations )
150
+ } )
151
+ this . _mutations = mergeObjects ( allMutations )
120
152
}
121
153
122
154
/**
@@ -144,74 +176,6 @@ export class Store {
144
176
} , { deep : true , sync : true } )
145
177
}
146
178
147
- /**
148
- * Set up the callable action functions exposed to components.
149
- * This method can be called multiple times for hot updates.
150
- * We keep the real action functions in an internal object,
151
- * and expose the public object which are just wrapper
152
- * functions that point to the real ones. This is so that
153
- * the reals ones can be hot reloaded.
154
- *
155
- * @param {Object } actions
156
- * @param {Boolean } [hot]
157
- */
158
-
159
- _setupActions ( actions , hot ) {
160
- this . _actions = Object . create ( null )
161
- actions = Array . isArray ( actions )
162
- ? mergeObjects ( actions )
163
- : actions
164
- Object . keys ( actions ) . forEach ( name => {
165
- this . _actions [ name ] = createAction ( actions [ name ] , this )
166
- if ( ! this . actions [ name ] ) {
167
- this . actions [ name ] = ( ...args ) => this . _actions [ name ] ( ...args )
168
- }
169
- } )
170
- // delete public actions that are no longer present
171
- // after a hot reload
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 )
200
- }
201
-
202
- /**
203
- * Setup the mutation handlers. Effectively a event listener.
204
- * This method can be called multiple times for hot updates.
205
- *
206
- * @param {Object } mutations
207
- */
208
-
209
- _setupMutations ( mutations ) {
210
- this . _mutations = Array . isArray ( mutations )
211
- ? mergeObjects ( mutations , true )
212
- : mutations
213
- }
214
-
215
179
/**
216
180
* Setup the middlewares. The devtools middleware is always
217
181
* included, since it does nothing if no devtool is detected.
@@ -244,27 +208,19 @@ export class Store {
244
208
}
245
209
}
246
210
247
- // export logger factory
248
- export { createLogger }
249
-
250
- // export install function
251
- export function install ( _Vue ) {
211
+ function install ( _Vue ) {
252
212
Vue = _Vue
253
- const _init = Vue . prototype . _init
254
- Vue . prototype . _init = function ( options ) {
255
- options = options || { }
256
- if ( options . store ) {
257
- this . $store = options . store
258
- } else if ( options . parent && options . parent . $store ) {
259
- this . $store = options . parent . $store
260
- }
261
- _init . call ( this , options )
262
- }
213
+ override ( Vue )
214
+ }
215
+
216
+ export {
217
+ install ,
218
+ createLogger
263
219
}
264
220
265
221
// also export the default
266
222
export default {
267
223
Store,
268
- createLogger ,
269
- install
224
+ install ,
225
+ createLogger
270
226
}
0 commit comments