Skip to content

Commit 7844f51

Browse files
committed
wip: new API
1 parent 3f080f3 commit 7844f51

File tree

3 files changed

+100
-121
lines changed

3 files changed

+100
-121
lines changed

src/index.js

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

56
let Vue
67

@@ -17,12 +18,14 @@ export class Store {
1718

1819
constructor ({
1920
state = {},
20-
actions = {},
2121
mutations = {},
22+
modules = {},
2223
middlewares = [],
23-
getters = {},
2424
strict = false
2525
} = {}) {
26+
this._dispatching = false
27+
this._rootMutations = this._mutations = mutations
28+
this._modules = modules
2629
// bind dispatch to self
2730
const dispatch = this.dispatch
2831
this.dispatch = (...args) => {
@@ -32,13 +35,9 @@ export class Store {
3235
this._vm = new Vue({
3336
data: state
3437
})
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)
4040
this._setupMiddlewares(middlewares, state)
41-
this._setupGetters(getters)
4241
// add extra warnings in strict mode
4342
if (strict) {
4443
this._setupMutationCheck()
@@ -103,20 +102,53 @@ export class Store {
103102
* Hot update actions and mutations.
104103
*
105104
* @param {Object} options
106-
* - {Object} [actions]
107105
* - {Object} [mutations]
106+
* - {Object} [modules]
108107
*/
109108

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)
120152
}
121153

122154
/**
@@ -144,74 +176,6 @@ export class Store {
144176
}, { deep: true, sync: true })
145177
}
146178

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-
215179
/**
216180
* Setup the middlewares. The devtools middleware is always
217181
* included, since it does nothing if no devtool is detected.
@@ -244,27 +208,19 @@ export class Store {
244208
}
245209
}
246210

247-
// export logger factory
248-
export { createLogger }
249-
250-
// export install function
251-
export function install (_Vue) {
211+
function install (_Vue) {
252212
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
263219
}
264220

265221
// also export the default
266222
export default {
267223
Store,
268-
createLogger,
269-
install
224+
install,
225+
createLogger
270226
}

src/override.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// export install function
2+
export default function (Vue) {
3+
const _init = Vue.prototype._init
4+
Vue.prototype._init = function (options) {
5+
options = options || {}
6+
const componentOptions = this.constructor.options
7+
// store injection
8+
const store = options.store || componentOptions.store
9+
if (store) {
10+
this.$store = store
11+
} else if (options.parent && options.parent.$store) {
12+
this.$store = options.parent.$store
13+
}
14+
// vuex option handling
15+
const vuex = options.vuex || componentOptions.vuex
16+
if (vuex) {
17+
const { state, actions } = vuex
18+
// state
19+
if (state) {
20+
options.computed = options.computed || {}
21+
Object.keys(state).forEach(key => {
22+
options.computed[key] = function vuexBoundGetter () {
23+
return state[key](this.$store.state)
24+
}
25+
})
26+
}
27+
// actions
28+
if (actions) {
29+
options.methods = options.methods || {}
30+
Object.keys(actions).forEach(key => {
31+
options.methods[key] = function vuexBoundAction (...args) {
32+
return actions[key](this.$store, ...args)
33+
}
34+
})
35+
}
36+
}
37+
_init.call(this, options)
38+
}
39+
}

src/util.js

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,6 @@ 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-
3519
/**
3620
* Merge an array of objects into one.
3721
*

0 commit comments

Comments
 (0)