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.
The official approach listing
~/store/index.ts
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'
~/utils/store-accessor.ts
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 }
Why I don't accept it
- I don't understand what we doing. Although the code volume is small, there are a lot of not obvious things. For example: Why we need to define the
plugins
constant? Why we need to export it? How and where we using this export? - I don't understand why we need to the acrobatics such as. If there are the other approaches, it must the more intuitive solution.
- I don't understand why we should to follow to this approach, not other one.
- It's not enough type-safe. 'any' has been used.
What I want to do
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.
Try to use the vuex store as usual
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)