From 43858fc2679cff7db65400233ab3310c4a464a4e Mon Sep 17 00:00:00 2001 From: ktsn Date: Sat, 15 Oct 2016 22:41:59 +0900 Subject: [PATCH 1/2] Declare parent module of local modules automatically --- src/mixin.ts | 16 ++++++++++++++++ test/mixin.ts | 45 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/mixin.ts b/src/mixin.ts index fecf370..a813a2c 100644 --- a/src/mixin.ts +++ b/src/mixin.ts @@ -1,5 +1,6 @@ import * as _Vue from 'vue' import { ComponentOptions } from 'vue' +import { Store } from 'vuex' import { PluginOptions, VuePrivate } from './declarations.d' import { registerLocalModule, unregisterLocalModule } from './register' @@ -21,6 +22,8 @@ export function applyMixin ( assert(this.$store, 'store must be injected') + ensureParent(this.$store, parentModulePath) + const localModule = this.$options.local.call(this) let name = localModule.name @@ -43,3 +46,16 @@ export function applyMixin ( } } as ComponentOptions<_Vue & VuePrivate>) } + +function ensureParent (store: Store, parentPath: string[]): void { + let state = store.state + const currentPath: string[] = [] + parentPath.forEach(key => { + state = state[key] + currentPath.push(key) + + if (typeof state === 'undefined') { + store.registerModule(currentPath, {}) + } + }) +} diff --git a/test/mixin.ts b/test/mixin.ts index a3886d2..2727418 100644 --- a/test/mixin.ts +++ b/test/mixin.ts @@ -6,21 +6,54 @@ import { applyMixin } from '../src/mixin' Vue.use(Vuex) describe('Global Mixin', () => { - let store: Vuex.Store - applyMixin(Vue, { parentModulePath: ['local'] }) - beforeEach(() => { - store = new Vuex.Store({ + it('auto declare parent module', () => { + const store: Vuex.Store = new Vuex.Store({}) + + new Vue({ + store, + local: () => ({ + name: 'test', + state: { value: 0 } + }) + }) + + assert(typeof store.state.local === 'object') + }) + + it('does not touch existing parent module', () => { + const store: Vuex.Store = new Vuex.Store({ modules: { - local: {} + local: { + modules: { + foo: { + state: { + value: 'foo' + } + } + } + } } }) + + new Vue({ + store, + local: () => ({ + name: 'test', + state: { value: 'test' } + }) + }) + + assert(store.state.local.foo.value === 'foo') + assert(store.state.local.test.value === 'test') }) it('binds local module', () => { + const store: Vuex.Store = new Vuex.Store({}) + const vm: any = new Vue({ store, local: () => ({ @@ -55,6 +88,8 @@ describe('Global Mixin', () => { }) it('remove local module when component is destroyed', () => { + const store: Vuex.Store = new Vuex.Store({}) + const vm: any = new Vue({ store, local: () => ({ From 3e5568296cb1eb1bb38179263f4cc02215cce978 Mon Sep 17 00:00:00 2001 From: ktsn Date: Sat, 15 Oct 2016 22:43:16 +0900 Subject: [PATCH 2/2] Update README about parent module --- README.md | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 0e9cb0f..4b32e90 100644 --- a/README.md +++ b/README.md @@ -29,13 +29,8 @@ Vue.use(VuexLocal, { parentModulePath: ['locals'] }) -export default new Vuex.Store({ - modules: { - // make sure to define the module that is - // specified by `parentModulePath` option - locals: {} - } -}) +// generate `locals` module automatically +export default new Vuex.Store({}) ``` Then, you can define a local module on each component. The component option will have `local` property that is a function returning a local module object.