A VueX wrapper to fully type your modules without more boilerplate
I'm realy greatly inspired by @mrcrowl work and his lib vuex-typex
I decided to take it a bit further and eliminating all boilerplate for declarating modules
It also comes with an vuex action logger
updateState
now accepts a callback with the state as param. All others update helpers removed
npm i vuex-typed-modules
#or
yarn add vuex-typed-modules
Create a test.module.ts
in your store folder
import { VuexModule } from 'vuex-typed-modules';
export const testModule = new VuexModule({
name: 'testModule',
state: {
count: 1,
},
mutations: {
addCount(state, number: number) {
state.count += number;
},
},
actions: {
async addCountAsync(_, count: number): Promise<void> {
await myAsyncFunction(count);
// Calling mutation
testModule.mutations.addCount(count);
},
},
});
Then in your main.ts
import { Database } from "vuex-typed-modules";
import { testModule } from '~modules'
const database = new Database({ logger: true });
const store = new Vuex.Store({
plugins: [database.deploy([testModule])];
})
new Vue({
store,
render: h => h(App)
}).$mount("#app");
import * as Modules from '~/modules';
const database = new Database({ logger: process.browser });
const modules = Object.keys(Modules).map((key) => Modules[key]);
export const plugins = [database.deploy(modules)];
export const state = () => ({});
<template>
<div class="hello">
{{ count }}
<button @click="increment">increment</button>
</div>
</template>
import { Component, Prop, Vue } from 'vue-property-decorator';
import { testModule } from '~/modules';
@Component
export default class Home extends Vue {
get count() {
return testModule.getters.count;
}
async increment() {
await testModule.actions.addCountAsync(2);
}
}
For dynamic modules, simply use the class VuexDynamicModule
instead
import { VuexDynamicModule } from 'vuex-typed-modules';
export const testModule = new VuexDynamicModule({
name: 'testModule',
state: {
count: 1,
},
actions: {
// Due to limitions of Typescript, I can't provide typings for infered mutations and getters inside the same object.
// It would make an infinite loop (I tried).
// For dynamic module you can fallback on "commit" "dispatch" and "getters"
exemple({ state, commit, dispatch, getters }, param: string) {
// ...
},
},
});
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { testModule } from '~/modules';
const ChildStoreModule = testModule.instance('child-store');
@Component
export default class TestView extends Vue {
get count() {
return ChildStoreModule.state.count;
}
created() {
ChildStoreModule.register();
}
beforeDestroy() {
ChildStoreModule.unregister();
}
}
</script>
Vuex types modules also add helpers functions on top of your module to prevent from writing short mutations
YourModule.helpers.resetState();
// Reset your module to the initial State
// You can specify only the property you want to update
YourModule.helpers.updateState({
count: 3,
});
// You can also give a callback function to have access to the current state
YourModule.helpers.updateState((state) => ({
count: state.count + 2,
}));
// And also mutate the state directly (A bit heavier on the update)
YourModule.helpers.updateState((state) => {
state.count++;
});