Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/victorgarciaesgi/vuex-typed-modules
🧰 A VueX wrapper to fully type your modules without boilerplate!
https://github.com/victorgarciaesgi/vuex-typed-modules
dynamic-modules vuex vuex-modules vuex-plugin vuex-store vuex-typed vuex-wrapper
Last synced: 2 days ago
JSON representation
🧰 A VueX wrapper to fully type your modules without boilerplate!
- Host: GitHub
- URL: https://github.com/victorgarciaesgi/vuex-typed-modules
- Owner: victorgarciaesgi
- Created: 2018-11-27T19:54:05.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2024-10-24T23:17:37.000Z (3 months ago)
- Last Synced: 2025-01-03T13:11:43.941Z (9 days ago)
- Topics: dynamic-modules, vuex, vuex-modules, vuex-plugin, vuex-store, vuex-typed, vuex-wrapper
- Language: TypeScript
- Homepage:
- Size: 331 KB
- Stars: 35
- Watchers: 6
- Forks: 8
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# 🧰 vuex-typed-modules
[![npm version][npm-version-src]][npm-version-href]
[![npm downloads][npm-downloads-src]][npm-downloads-href]
[![npm downloads][npm-total-downloads-src]][npm-downloads-href][npm-version-src]: https://img.shields.io/npm/v/vuex-typed-modules.svg
[npm-version-href]: https://www.npmjs.com/package/vuex-typed-modules
[npm-downloads-src]: https://img.shields.io/npm/dm/vuex-typed-modules.svg
[npm-total-downloads-src]: https://img.shields.io/npm/dt/vuex-typed-modules.svg
[npm-downloads-href]: https://www.npmjs.com/package/vuex-typed-modulesA VueX 3 & 4 wrapper that provides type safe hooks and handlers to your Vuex Store modules with less code!
> 4.x Support Vue 2 & 3, and Vuex 3 & 4 and added composition-api support (Thanks to `vue-demi`)
> 3.x Working with Vue 2, and Vue 3 with Vuex4 (but not hooks)
## Installation
```bash
npm i vuex-typed-modules
#or
yarn add vuex-typed-modules
```# Usage for version `4.x`
## Define Module and hook
```typescript
import { createVuexModule } from 'vuex-typed-modules';export const [testModule, useTestModule] = createVuexModule({
name: 'testModule',
state: {
count: 1,
},
mutations: {
addCount(state, number: number) {
state.count += number;
},
},
actions: {
async addCountAsync(_, count: number): Promise {
await myAsyncFunction(count);
// Calling mutation
testModule.mutations.addCount(count);
},
},
});
```## Module declaration (For 4.x and 3.x)
In your `main.ts`
```typescript
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])];
})// If you're using Vue 3:
createApp(App).use(store).mount("#app");// If you're using Vue 2:
new Vue({
store,
render: h => h(App)
}).$mount("#app");
```## For Nuxt.js
```typescript
// store/index.ts
import { Database } from 'vuex-typed-modules';
import { testModule } from '~modules';const database = new Database({ logger: process.browser });
export const plugins = [database.deploy([testModule])];export const state = () => ({});
```## Usage in your components or in other modules!
```html
{{ count }}
increment
```
```typescript
import { defineComponent, onBeforeUnmount } from 'vue';
import { testModule } from '~/modules';export default defineComponent({
name: 'Home',
setup() {
const {
state: { count },
actions: { increment },
} = useChildStoreModule();return {
count,
increment,
};
},
});
```## Note
Store hooks return refs for the state. It can be overwridden by using the option `unwrap`
With Refs
```ts
// You can destructure state when using refs
const {
state: { count },
} = useTestModule(); // count is of type `Ref`
console.log(count.value);
```Without Refs
```ts
// If you destructure the state, it will loses reactivity
const { state } = useTestModule({ unwrap: true });
state.count; // count is of type `number`
```## Dynamic Modules
For dynamic modules, simply use the class `VuexDynamicModule` instead
```typescript
import { createVuexDynamicModule } from 'vuex-typed-modules';export const dynamicModule = createVuexDynamicModule({
name: 'dynamicModule',
logger: false,
state: {
count: 1,
type: null,
},
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) {
// ...
},
},
});
```### Usage
```vue
import { defineComponent, onBeforeUnmount } from 'vue';
import { dynamicModule } from '~/modules';const [ChildStoreModule, useChildStoreModule] = dynamicModule.instance('child-store');
// Dot not declare it in other files, only import it from hereexport default defineComponent({
name: 'TestView',
setup() {
ChildStoreModule.register();
const {
state: { count },
} = useChildStoreModule();onBeforeUnmount(() => {
ChildStoreModule.unregister();
});return {
count,
};
},
});```
## Default module helpers
Vuex types modules also add helpers functions on top of your module to prevent from writing short mutations
```typescript
testModule.resetState();
// Reset your module to the initial State
``````typescript
// You can specify only the property you want to update
testModule.updateState({
count: 3,
});// You can also give a callback function to have access to the current state
testModule.updateState((state) => ({
count: state.count + 2,
}));// And also mutate the state directly (A bit heavier on the update)
testModule.updateState((state) => {
state.count++;
});
```# -------------------------------------------
# Usage for `3.x`
## Define Module
Create a `test.module.ts` in your store folder
```typescript
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 {
await myAsyncFunction(count);
// Calling mutation
testModule.mutations.addCount(count);
},
},
});
```## Usage in your components or in other modules!
```html
{{ count }}
increment
```
```typescript
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);
}
}
```# Tests
```typescript
// user.spec.ts
import { createTestStore } from 'vuex-typed-modules';
import { createLocalVue } from '@vue/test-utils';
// import state, actions, mutations and getters from some store moduleconst configStore = {
state,
actions,
mutations,
getters,
};const localVue = createLocalVue();
localVue.use(Vuex);const store = createTestStore(configStore);
describe('User Module', () => {
it('name should be empty', () => {
expect(store.state.name).toBe('');
});
it('name should change to Foo', () => {
store.dispatch('CHANGE_NAME', 'Foo');
expect(store.state.name).toBe('Foo');
});
});
```