Skip to content

Commit

Permalink
feat: preserve state with registerModule (#837)
Browse files Browse the repository at this point in the history
  • Loading branch information
blake-newman authored and yyx990803 committed Oct 11, 2017
1 parent 0e9756b commit 4c1841e
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 5 deletions.
4 changes: 3 additions & 1 deletion docs/en/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,12 @@ const store = new Vuex.Store({ ...options })
Most commonly used in plugins. [Details](plugins.md)
- **`registerModule(path: string | Array<string>, module: Module)`**
- **`registerModule(path: string | Array<string>, module: Module, options?: Object)`**
Register a dynamic module. [Details](modules.md#dynamic-module-registration)
`options` can have `preserveState: true` that allows to preserve the previous state. Useful with Server Side Rendering.
- **`unregisterModule(path: string | Array<string>)`**
Unregister a dynamic module. [Details](modules.md#dynamic-module-registration)
Expand Down
2 changes: 2 additions & 0 deletions docs/en/modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,8 @@ Dynamic module registration makes it possible for other Vue plugins to also leve

You can also remove a dynamically registered module with `store.unregisterModule(moduleName)`. Note you cannot remove static modules (declared at store creation) with this method.

It may be likely that you want to preserve the previous state when registering a new module, such as preserving state from a Server Side Rendered app. You can do achieve this with `preserveState` option: `store.registerModule('a', module, { preserveState: true })`

### Module Reuse

Sometimes we may need to create multiple instances of a module, for example:
Expand Down
4 changes: 2 additions & 2 deletions src/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ export class Store {
})
}

registerModule (path, rawModule) {
registerModule (path, rawModule, options = {}) {
if (typeof path === 'string') path = [path]

if (process.env.NODE_ENV !== 'production') {
Expand All @@ -170,7 +170,7 @@ export class Store {
}

this._modules.register(path, rawModule)
installModule(this, this.state, path, this._modules.get(path))
installModule(this, this.state, path, this._modules.get(path), options.preserveState)
// reset store to update getters...
resetStoreVM(this, this.state)
}
Expand Down
22 changes: 22 additions & 0 deletions test/unit/modules.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,28 @@ describe('Modules', () => {
store.commit('a/foo')
expect(mutationSpy).toHaveBeenCalled()
})

it('dynamic module registration preserving hydration', () => {
const store = new Vuex.Store({})
store.replaceState({ a: { foo: 'state' }})
const actionSpy = jasmine.createSpy()
const mutationSpy = jasmine.createSpy()
store.registerModule('a', {
namespaced: true,
getters: { foo: state => state.foo },
actions: { foo: actionSpy },
mutations: { foo: mutationSpy }
}, { preserveState: true })

expect(store.state.a.foo).toBe('state')
expect(store.getters['a/foo']).toBe('state')

store.dispatch('a/foo')
expect(actionSpy).toHaveBeenCalled()

store.commit('a/foo')
expect(mutationSpy).toHaveBeenCalled()
})
})

// #524
Expand Down
8 changes: 6 additions & 2 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ export declare class Store<S> {
subscribe<P extends MutationPayload>(fn: (mutation: P, state: S) => any): () => void;
watch<T>(getter: (state: S) => T, cb: (value: T, oldValue: T) => void, options?: WatchOptions): () => void;

registerModule<T>(path: string, module: Module<T, S>): void;
registerModule<T>(path: string[], module: Module<T, S>): void;
registerModule<T>(path: string, module: Module<T, S>, options?: ModuleOptions): void;
registerModule<T>(path: string[], module: Module<T, S>, options?: ModuleOptions): void;

unregisterModule(path: string): void;
unregisterModule(path: string[]): void;
Expand Down Expand Up @@ -96,6 +96,10 @@ export interface Module<S, R> {
modules?: ModuleTree<R>;
}

export interface ModuleOptions{
preserveState?: boolean
}

export interface GetterTree<S, R> {
[key: string]: Getter<S, R>;
}
Expand Down
4 changes: 4 additions & 0 deletions types/test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,10 @@ namespace RegisterModule {
state: { value: 2 }
});

store.registerModule(["a", "b"], {
state: { value: 2 }
}, { preserveState: true });

store.unregisterModule(["a", "b"]);
store.unregisterModule("a");
}
Expand Down

0 comments on commit 4c1841e

Please sign in to comment.