Skip to content

Commit 00d9007

Browse files
committed
handle option merging
1 parent 9d24f8f commit 00d9007

File tree

2 files changed

+87
-19
lines changed

2 files changed

+87
-19
lines changed

src/override.js

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
1-
// export install function
21
export default function (Vue) {
2+
// override init and inject vuex init procedure
33
const _init = Vue.prototype._init
4-
Vue.prototype._init = function (options) {
5-
options = options || {}
6-
const componentOptions = this.constructor.options
4+
Vue.prototype._init = function (options = {}) {
5+
options.init = options.init
6+
? [vuexInit].concat(options.init)
7+
: vuexInit
8+
_init.call(this, options)
9+
}
10+
11+
function vuexInit () {
12+
const options = this.$options
13+
const { store, vuex } = options
714
// store injection
8-
const store = options.store || componentOptions.store
915
if (store) {
1016
this.$store = store
1117
} else if (options.parent && options.parent.$store) {
1218
this.$store = options.parent.$store
1319
}
1420
// vuex option handling
15-
const vuex = options.vuex || componentOptions.vuex
1621
if (vuex) {
1722
if (!this.$store) {
1823
console.warn(
@@ -21,32 +26,52 @@ export default function (Vue) {
2126
)
2227
}
2328
let { state, getters, actions } = vuex
24-
// getters
29+
// handle deprecated state option
2530
if (state && !getters) {
2631
console.warn(
27-
'[vuex] vuex.state option has been deprecated. ' +
32+
'[vuex] vuex.state option will been deprecated in 1.0. ' +
2833
'Use vuex.getters instead.'
2934
)
3035
getters = state
3136
}
37+
// getters
3238
if (getters) {
3339
options.computed = options.computed || {}
34-
Object.keys(getters).forEach(key => {
35-
options.computed[key] = function vuexBoundGetter () {
36-
return getters[key].call(this, this.$store.state)
37-
}
38-
})
40+
for (let key in getters) {
41+
options.computed[key] = makeBoundGetter(getters[key])
42+
}
3943
}
4044
// actions
4145
if (actions) {
4246
options.methods = options.methods || {}
43-
Object.keys(actions).forEach(key => {
44-
options.methods[key] = function vuexBoundAction (...args) {
45-
return actions[key].call(this, this.$store, ...args)
46-
}
47-
})
47+
for (let key in actions) {
48+
options.methods[key] = makeBoundAction(actions[key])
49+
}
4850
}
4951
}
50-
_init.call(this, options)
52+
}
53+
54+
function makeBoundGetter (getter) {
55+
return function vuexBoundGetter () {
56+
return getter.call(this, this.$store.state)
57+
}
58+
}
59+
60+
function makeBoundAction (action) {
61+
return function vuexBoundAction (...args) {
62+
return action.call(this, this.$store, ...args)
63+
}
64+
}
65+
66+
// option merging
67+
const merge = Vue.config.optionMergeStrategies.computed
68+
Vue.config.optionMergeStrategies.vuex = (toVal, fromVal) => {
69+
if (!toVal) return fromVal
70+
if (!fromVal) return toVal
71+
return {
72+
getters: merge(toVal.getters, fromVal.getters),
73+
state: merge(toVal.state, fromVal.state),
74+
actions: merge(toVal.actions, fromVal.actions)
75+
}
5176
}
5277
}

test/test.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,4 +281,47 @@ describe('Vuex', () => {
281281
store.state.a++
282282
}).to.throw(/Do not mutate vuex store state outside mutation handlers/)
283283
})
284+
285+
it('option merging', function () {
286+
const store = new Vuex.Store({
287+
state: {
288+
a: 1,
289+
b: 2
290+
},
291+
mutations: {
292+
[TEST] (state, n) {
293+
state.a += n
294+
}
295+
}
296+
})
297+
const vm = new Vue({
298+
store,
299+
vuex: {
300+
getters: {
301+
a: state => state.a
302+
},
303+
actions: {
304+
test: ({ dispatch }, n) => dispatch(TEST, n)
305+
}
306+
},
307+
mixins: [{
308+
vuex: {
309+
getters: {
310+
b: state => state.b
311+
},
312+
actions: {
313+
testPlusOne: ({ dispatch }, n) => dispatch(TEST, n + 1)
314+
}
315+
}
316+
}]
317+
})
318+
expect(vm.a).to.equal(1)
319+
expect(vm.b).to.equal(2)
320+
vm.test(2)
321+
expect(vm.a).to.equal(3)
322+
expect(store.state.a).to.equal(3)
323+
vm.testPlusOne(2)
324+
expect(vm.a).to.equal(6)
325+
expect(store.state.a).to.equal(6)
326+
})
284327
})

0 commit comments

Comments
 (0)