Dynamic modules
Vanilla, strongly-typed store accessor.
You can also use typed-vuex
with dynamic modules.
Variable usage
Sample module
modules/dynamic-module.ts
export const namespaced = true
export const state = () => ({
emails: [] as string[],
})
export const mutations = mutationTree(state, {
addEmail(state, newEmail: string) {
state.emails.push(newEmail)
},
})
Accessing the module
You might want to use the store
components/my-component.vue
import Vue from 'vue
import { useAccessor, getAccessorType } from 'typed-vuex'
import * as dynamicModule from '~/modules/dynamic-module'
const accessorType = getAccessorType(dynamicModule)
export default Vue.extend({
data: () => ({
accessor: null as typeof accessorType | null,
}),
beforeCreated() {
// make sure the namespaces match!
this.$store.registerModule('dynamicModule', dynamicModule, {
preserveState: false,
})
const accessor = useAccessor(this.$store, dynamicModule, 'dynamicModule')
// this works and is typed
accessor.addEmail('my@email.com')
// but you might want to save the accessor for use elsewhere in your component
this.accessor = accessor
},
methods: {
anotherMethod() {
// ... such as here
if (this.accessor) {
this.accessor.addEmail('my@email.com')
}
}
}
})
Global usage
You can also register dynamic module on global level for your accessor. This can be a risky way, but can also be a way
for large projects with no able of using useAccessor
as variable.
Module definition
store/index.ts
import * as myImportedModule from '~/modules/myImportedModule'
import * as myNestedModule from '~/modules/myNestedModule'
import * as myDynamicModuleNoSpread from '~/modules/myImportedModuleNoSpread'
export const accessorType = getAccessorType({
state,
getters,
mutations,
actions,
modules: {
submodule: {
//add this for module to show as possibly-undefined when using $accessor
dynamic: true,
namespaced: true,
...myImportedModule,
modules: {
myNestedModule,
},
},
//You can add `export const dynamic = true;` inside module so you don't need to use spread operator in that case
//View the example below
submoduleWithoutSpread: myDynamicModuleNoSpread,
},
})
modules/myImportedModuleNoSpread.ts
export const dynamic = true;
export const state = () => ({
//...
});
Modules registration
components/my-component.vue
import Vue from 'vue
//Import from typed-vuex is not required in Nuxt
import { registerModule, unregisterModule } from 'typed-vuex'
import myImportedModule from '~/modules/myImportedModule'
import myNestedModule from '~/modules/myNestedModule'
export default Vue.extend({
beforeCreated() {
//Or this.$accessorRegisterModule('myImportedModule', myImportedModule) in Nuxt
registerModule('myImportedModule', this.$store, this.$accessor, myImportedModule)
//Or this.$accessorRegisterModule(['myImportedModule', 'myNestedModule'], myImportedModule) in Nuxt
registerModule(['myImportedModule', 'myNestedModule'], this.$store, this.$accessor, myNestedModule)
//You can also register two modules at once, but you MUST include namespaced: true in that case
//this.$accessorRegisterModule('myImportedModule', {...}) syntax in Nuxt
registerModule('myImportedModule', {
...myImportedModule,
modules: {
myNestedModule: {
//required for correct usage, especially in Nuxt
namespaced: true,
...myNestedModule,
},
},
})
//To unregister module(s), simply call this
//this.$accessorUnregisterModule('myImportedModule') in Nuxt
unregisterModule('myImportedModule', this.$store, this.$accessor)
},
methods: {
anotherMethod() {
//If you are not sure about if module will always exist,
// it is recommended to enable dynamic: true in store and always check for undefined
if (this.accessor) {
this.$accessor.myImportedModule?.myNestedModule?.addEmail('my@email.com')
}
}
}
})
Typed $accessor methods
If you want methods $accessorRegisterModule
and $accessorUnregisterModule
to be typed, please add nuxt-typed-vuex
package to tsconfig.json
types.
tsconfig.json
{
{
"types": [
"nuxt-typed-vuex"
]
}
}