There are many possible ways to construct your modules.
One of the most popular approaches is vuex-module-decorators.
Well, where at least two approaches has been introduced? The documentations are introducing just one approach and most articles are refers to it.
import { Store } from 'vuex'
import { initialiseStores } from '~/utils/store-accessor'
const initializer = (store: Store<any>) => initialiseStores(store)
export const plugins = [initializer]
export * from '~/utils/store-accessor'
import { Store } from 'vuex'
import { getModule } from 'vuex-module-decorators'
import example from '~/store/example'
let exampleStore: example
function initialiseStores(store: Store<any>): void {
exampleStore = getModule(example, store)
}
export { initialiseStores, exampleStore }
plugins
constant? Why we need to export it? How and where we using this export?If it's possible, I want to use the 'vuex-module-decorators' as usual, or, at least understand what going on and develop more clean solution.
The standard usage of dynamic modules in 'vuex-module-decorators' is:
import store from "@store";
import { Module, VuexModule } from "vuex-module-decorators";
@Module({
name: "PRODUCTS_MANAGER",
dynamic: true,
namespaced: true,
store
})
class ProductsManagerStoreModule extends VuexModule {}
But how we get the store
instance in Nuxt TypeScript application?
The Nuxt takes out the vuex store from us (same as routing and webpack control) to make the development simply, but here is the reverse effect.
It's interesting, but it works in development environment, but not in production.
store/index.ts
import Vuex, { Store } from "vuex";
export const store: Store<unknown> = new Vuex.Store({});
export default store;
pages/index.vue
import { Component, Vue } from "nuxt-property-decorator"
import { getModule } from "nuxt-property-decorator";
import TestStoreModule from "./../Store/TestStoreModule";
@Component
export default class extends Vue {
private readonly title: string = "It Works!";
private mounted(): void {
console.log("=========");
console.log(getModule(TestStoreModule).currentCount);
}
}
store/TestStoreModule.ts
import { Module, VuexModule, Mutation } from "vuex-module-decorators";
import store from "./index";
@Module({
name: "TestStoreModule",
namespaced: true,
dynamic: true,
store
})
export default class TestStoreModule extends VuexModule {
private count: number = 0
@Mutation
public increment(delta: number): void {
this.count += delta
}
@Mutation
public decrement(delta: number): void {
this.count -= delta
}
public get currentCount(): number {
return this.count;
}
}
But after production build, I have below error displaying in console:
ERROR [nuxt] store/index.ts should export a method that returns a Vuex instance.
🌎 Application in above state (GitHub repository) (The project structure a little bit different, I am sorry).
I tried to fix it as has been told. Now, store/index.ts
is:
// config.rawError = true;
/* 〔 see 〕 https://develop365.gitlab.io/nuxtjs-2.1.0-doc/pt-BR/guide/vuex-store/ */
export default function createStore(): Store<unknown> {
return new Vuex.Store({});
}
The TestStoreModule
can not refer to store
now (if can, how?).
@Module({
name: "TestStoreModule",
namespaced: true,
stateFactory: true
})
export default class TestStoreModule extends VuexModule { /* ... */ }
In the component, tried to access to store module as:
console.log(getModule(TestStoreModule, this.$store).currentCount);
The output is:
Seems like the 'this' problem. If we output the console.log(getModule(TestStoreModule, this.$store));
and call the currentCount
from Chrome console:
we get the error:
Exception: TypeError: Cannot read property 'count' of undefined at Object.get
(webpack-internal:///./node_modules/vuex-module-decorators/dist/esm/index.js:165:36)
at Object.r (<anonymous>:1:83)
When I asked this question, I did not know that it's possible to use the dynamic modules in Nuxt as in plain Vue application. The dynamic modules gives the cleanest syntax and makes the effect like each module is independent. No need in hacks like store-accessor.ts
; no need to gather all modules is single directory. This approach is my select and recommendation.
The question Dynamic vuex store modules with NuxtJS and vuex-module-decorators covers the setup of vuex-module-decorators
for Nuxt.
In this way, answering to current question, in store/index.ts
we can create the store instance, import it and use in each dynamic module:
import Vue from "vue";
import Vuex, { Store } from "vuex";
Vue.use(Vuex);
export const store: Store<unknown> = new Vuex.Store<unknown>({});