Skip to content

Commit f71e27b

Browse files
author
tiagoroldao
committed
Fixed action/mutation/getter proxies on submodules
1 parent 1373ca5 commit f71e27b

File tree

6 files changed

+31
-23
lines changed

6 files changed

+31
-23
lines changed

src/actions.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,13 @@ export function action(...params:any[]) {
1818

1919
if( firstParam === undefined ) return handleMutateActionMode;
2020

21-
if( firstParam instanceof VuexModule || firstParam instanceof LegacyVuexModule || typeof firstParam === "object" ) {
21+
if( firstParam instanceof VuexModule || firstParam instanceof LegacyVuexModule ) {
2222
return handleMutateActionMode( firstParam, params[ 1 ], params[ 2 ] )
2323
}
24-
//@ts-ignore
2524
switch( firstParam.mode ) {
2625
case "raw": return handleRawActionMode;
2726
case "mutate": return handleMutateActionMode;
28-
default: return handleMutateActionMode;
27+
default: return handleMutateActionMode( firstParam, params[ 1 ], params[ 2 ] );
2928
}
3029

3130
}

src/module.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,10 @@ export function getNamespacedPath( cls :VuexModuleConstructor ) {
108108

109109
const namespaced = cls.prototype.__options__ && cls.prototype.__options__.namespaced;
110110

111-
if( namespaced ) cls.prototype.__namespacedPath__ = namespaced.split("/")[0]
111+
if( namespaced ) {
112+
const namePaths = namespaced.split("/");
113+
cls.prototype.__namespacedPath__ = namePaths[namePaths.length - 1] || namePaths[namePaths.length - 2];
114+
}
112115

113116
return cls.prototype.__namespacedPath__;
114117

src/proxy.ts

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { extractVuexModule } from "./module";
1+
import { extractVuexModule, getNamespacedPath } from "./module";
22
import { VuexModuleConstructor, Map, VuexModule, ProxyWatchers } from "./interfaces";
33
import { getClassPath, toCamelCase, refineNamespacedPath } from "./utils";
44

@@ -36,7 +36,7 @@ export function createProxy<T extends typeof VuexModule>( $store :any, cls :T )
3636
// If field is a getter use the normal getter path if not use internal getters.
3737
if( typeof field === "string" && getterNames.indexOf( field ) > -1 ) {
3838
return $store.watch(
39-
() => $store.getters[ namespacedPath + field ],
39+
() => ($store.rootGetters || $store.getters)[ namespacedPath + field ],
4040
callback,
4141
options,
4242
)
@@ -45,7 +45,7 @@ export function createProxy<T extends typeof VuexModule>( $store :any, cls :T )
4545
const className = cls.name.toLowerCase();
4646

4747
return $store.watch(
48-
() => $store.getters[ namespacedPath + `__${className}_internal_getter__`]( field ),
48+
() => ($store.rootGetters || $store.getters)[ namespacedPath + `__${className}_internal_getter__`]( field ),
4949
callback,
5050
options,
5151
)
@@ -251,13 +251,13 @@ function createLocalWatchers( cls :VuexModuleConstructor, $store :Map, namespace
251251

252252
if( fieldIsAnExplicitGetter ) {
253253
$store.watch(
254-
() => $store.getters[ namespacedPath + field ],
254+
() => ($store.rootGetters || $store.getters)[ namespacedPath + field ],
255255
proxiedWatchFunc,
256256
)
257257
}
258258
else { // This is so we can also watch implicit getters.
259259
$store.watch(
260-
() => $store.getters[ namespacedPath + `__${className}_internal_getter__` ]( field ),
260+
() => ($store.rootGetters || $store.getters)[ namespacedPath + `__${className}_internal_getter__` ]( field ),
261261
proxiedWatchFunc,
262262
)
263263
}
@@ -270,7 +270,8 @@ function createSubModuleProxy( $store :Map, cls:VuexModuleConstructor, proxy :Ma
270270
const store = cls.prototype.__store_cache__ || $store;
271271
for( let field in modules ) {
272272
const subModuleClass = cls.prototype.__submodules_cache__[ field ] as VuexModuleConstructor;
273-
subModuleClass.prototype.__namespacedPath__ = cls.prototype.__namespacedPath__ + "/" + subModuleClass.prototype.__namespacedPath__;
273+
const namespacedPath = getNamespacedPath(subModuleClass);
274+
subModuleClass.prototype.__namespacedPath__ = cls.prototype.__namespacedPath__ + "/" + namespacedPath;
274275
proxy[ field ] = createProxy( store, subModuleClass );
275276
}
276277

@@ -310,17 +311,19 @@ function createGettersAndMutationProxyFromState({ cls, proxy, state, $store, nam
310311
get: () => {
311312
// When creating local proxies getters doesn't exist on that context, so we have to account
312313
// for that.
313-
if( $store.getters ) {
314-
return $store.getters[ namespacedPath + `__${className}_internal_getter__` ]( path )
314+
const getters = $store.rootGetters || $store.getters;
315+
if( getters ) {
316+
const getterPath = refineNamespacedPath(cls.prototype.__namespacedPath__) + `__${className}_internal_getter__`;
317+
return getters[ getterPath ]( path )
315318
}else return $store[ `__${className}_internal_getter__` ]( path )
316319
},
317320
set: payload => {
318321
const commit = $store.commit || cls.prototype.__store_cache__.commit;
319-
if( commit ) commit( refineNamespacedPath( cls.prototype.__namespacedPath__ ) + `__${className}_internal_mutator__`, { field: path, payload });
322+
if( commit ) commit( refineNamespacedPath( cls.prototype.__namespacedPath__ ) + `__${className}_internal_mutator__`, { field: path, payload }, { root: true });
320323
else {
321324
// We must be creating local proxies hence, $store.commit doesn't exist
322325
const store = cls.prototype.__context_store__!;
323-
store.commit( `__${className}_internal_mutator__`, { field: path, payload })
326+
store.commit( `__${className}_internal_mutator__`, { field: path, payload }, { root: true })
324327
}
325328
},
326329
})
@@ -401,7 +404,7 @@ function __createGettersAndMutationProxyFromState({ cls, proxy, state, $store, n
401404
else {
402405
// We must be creating local proxies hence, $store.commit doesn't exist
403406
const store = cls.prototype.__context_store__!;
404-
store.commit( `__${className}_internal_mutator__`, { field, payload })
407+
store.commit( `__${className}_internal_mutator__`, { field, payload }, { root: true })
405408
}
406409
},
407410
})
@@ -437,7 +440,7 @@ function createExplicitMutationsProxy( cls :VuexModuleConstructor, proxy :Map, $
437440
);
438441

439442
for( let field in mutations ) {
440-
proxy[ field ] = ( payload :any ) => commit( namespacedPath + field, payload )
443+
proxy[ field ] = ( payload :any ) => commit( namespacedPath + field, payload, { root: true } )
441444
}
442445

443446
}
@@ -465,21 +468,23 @@ function createGettersAndGetterMutationsProxy({ cls, getters, mutations, proxy,
465468

466469
Object.defineProperty( proxy, field, {
467470
get: () => {
468-
if( $store.getters ) return $store.getters[ namespacedPath + field ]
471+
const storeGetters = namespacedPath ? $store.rootGetters : $store.getters;
472+
if( storeGetters ) return storeGetters[ namespacedPath + field ]
469473
else return $store[ namespacedPath + field ];
470474
},
471-
set: ( payload :any ) => $store.commit( namespacedPath + field, payload ),
475+
set: ( payload :any ) => $store.commit( namespacedPath + field, payload, { root: !!namespacedPath } ),
472476
})
473477

474478
continue;
475479
}
476480

477481
// The field has only a getter.
478-
if( proxy[ field ] ) continue;
482+
if( Object.prototype.hasOwnProperty.call(proxy, field) ) continue;
479483

480484
Object.defineProperty( proxy, field, {
481485
get: () => {
482-
if( $store.getters ) return $store.getters[ namespacedPath + field ];
486+
const storeGetters = $store.rootGetters || $store.getters;
487+
if( storeGetters ) return storeGetters[ namespacedPath + field ];
483488
else return $store[ namespacedPath + field ];
484489
}
485490
})

src/utils.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ export function toCamelCase(str :string){
33
}
44

55
export function getClassPath( path :string ) {
6+
if (!path) { return ''; }
67
const arr = path.split( "/" );
78
return arr[ arr.length - 1 ];
89
}

test/create-proxy.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import Vuex, {Store} from 'vuex'
33
// @ts-ignore
44
import { createLocalVue } from '@vue/test-utils'
5-
import { Module, VuexModule, getter, mutation, action } from '../src'
5+
import { Module, VuexModule, getter, mutation, action, getRawActionContext } from '../src'
66

77

88
interface Name {

test/extract-vuex-module.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ describe('ExtractVuexModule', () => {
9090
it('should extract all properties as state in a function for NuxtUserStore', () => {
9191
const { state } = NuxtUserStore.ExtractVuexModule( NuxtUserStore );
9292
expect( typeof state ).toBe( "function" );
93-
expect( state() ).toEqual({
93+
expect( (state as Function)() ).toEqual({
9494
firstname: "Michael",
9595
lastname: "Olofinjana",
9696
speciality: "JavaScript",
@@ -103,7 +103,7 @@ describe('ExtractVuexModule', () => {
103103
const { getters } = UserStore.ExtractVuexModule(UserStore)
104104
// Note all states are automatically accessible as getters.
105105
// This makes th `@getter` decorator redundant. But we have it for backwards compatibility.
106-
expect(Object.keys(getters)).toEqual([ 'fullName', `__${UserStore.name.toLowerCase()}_internal_getter__` ])
106+
expect(Object.keys(getters)).toEqual([ 'fullName', 'speciality', 'occupation', `__${UserStore.name.toLowerCase()}_internal_getter__` ])
107107
})
108108

109109
it('should extract all actions', () => {

0 commit comments

Comments
 (0)