• Stars
    star
    1,796
  • Rank 25,870 (Top 0.6 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created over 6 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

TypeScript/ES7 Decorators to create Vuex modules declaratively

vuex-module-decorators

Usage Guide Detailed Guide: https://championswimmer.in/vuex-module-decorators/

Typescript/ES7 Decorators to make Vuex modules a breeze

Build Status npm:size:gzip cdn:min:gzip codecov npm npm npm type definitions Maintainability Codacy Badge codebeat badge Total alerts Language grade: JavaScript

Patrons

While I have a day job and I really maintain open source libraries for fun, any sponsors are extremely graciously thanked for their contributions, and goes a long way 😇 ❤️

CHANGELOG

  • There are major type-checking changes (could be breaking) in v0.9.7

  • There are major usage improvements (non backwards compatible) in 0.8.0

Please check CHANGELOG

Examples

Read the rest of the README to figure out how to use, or if you readily want to jump into a production codebase and see how this is used, you can check out -

Installation

npm install -D vuex-module-decorators

Babel 6/7

NOTE This is not necessary for vue-cli@3 projects, since @vue/babel-preset-app already includes this plugin

  1. You need to install babel-plugin-transform-decorators

TypeScript

  1. set experimentalDecorators to true
  2. For reduced code with decorators, set importHelpers: true in tsconfig.json
  3. (only for TypeScript 2) set emitHelpers: true in tsconfig.json

Configuration

Using with target: es5

NOTE Since version 0.9.3 we distribute as ES5, so this section is applicable only to v0.9.2 and below

This package generates code in es2015 format. If your Vue project targets ES6 or ES2015 then you need not do anything. But in case your project uses es5 target (to support old browsers), then you need to tell Vue CLI / Babel to transpile this package.

// in your vue.config.js
module.exports = {
  /* ... other settings */
  transpileDependencies: ['vuex-module-decorators']
}

Usage

The conventional old & boring way

Remember how vuex modules used to be made ?

const moduleA = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  state: { ... },
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

Hello Decorators !

Well not anymore. Now you get better syntax. Inspired by vue-class-component

import { Module, VuexModule, Mutation, Action } from 'vuex-module-decorators'

@Module
export default class Counter2 extends VuexModule {
  count = 0

  @Mutation
  increment(delta: number) {
    this.count += delta
  }
  @Mutation
  decrement(delta: number) {
    this.count -= delta
  }

  // action 'incr' commits mutation 'increment' when done with return value as payload
  @Action({ commit: 'increment' })
  incr() {
    return 5
  }
  // action 'decr' commits mutation 'decrement' when done with return value as payload
  @Action({ commit: 'decrement' })
  decr() {
    return 5
  }
}

async MutationAction === magic

Want to see something even better ?

import { Module, VuexModule, MutationAction } from 'vuex-module-decorators'
import { ConferencesEntity, EventsEntity } from '@/models/definitions'

@Module
export default class HGAPIModule extends VuexModule {
  conferences: Array<ConferencesEntity> = []
  events: Array<EventsEntity> = []

  // 'events' and 'conferences' are replaced by returned object
  // whose shape must be `{events: [...], conferences: [...] }`
  @MutationAction({ mutate: ['events', 'conferences'] })
  async fetchAll() {
    const response: Response = await getJSON('https://hasgeek.github.io/events/api/events.json')
    return response
  }
}

Automatic getter detection

@Module
class MyModule extends VuexModule {
  wheels = 2

  @Mutation
  incrWheels(extra) {
    this.wheels += extra
  }

  get axles() {
    return this.wheels / 2
  }
}

this is turned into the equivalent

const module = {
  state: { wheels: 2 },
  mutations: {
    incrWheels(state, extra) {
      state.wheels += extra
    }
  },
  getters: {
    axles: (state) => state.wheels / 2
  }
}

Putting into the store

Use the modules just like you would earlier

import Vue from 'nativescript-vue'
import Vuex, { Module } from 'vuex'

import counter from './modules/Counter2'
import hgapi from './modules/HGAPIModule'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {},
  modules: {
    counter,
    hgapi
  }
})

Module re-use, use with NuxtJS

If you need to support module reuse or to use modules with NuxtJS, you can have a state factory function generated instead of a static state object instance by using stateFactory option to @Module, like so:

@Module({ stateFactory: true })
class MyModule extends VuexModule {
  wheels = 2

  @Mutation
  incrWheels(extra) {
    this.wheels += extra
  }

  get axles() {
    return this.wheels / 2
  }
}

this is turned into the equivalent

const module = {
  state() {
    return { wheels: 2 }
  },

  mutations: {
    incrWheels(state, extra) {
      state.wheels += extra
    }
  },
  getters: {
    axles: (state) => state.wheels / 2
  }
}

Dynamic Modules

Vuex allows us to register modules into store at runtime after store is constructed. We can do the following to create dynamic modules

interface StoreType {
  mm: MyModule
}
// Declare empty store first
const store = new Vuex.Store<StoreType>({})

// Create module later in your code (it will register itself automatically)
// In the decorator we pass the store object into which module is injected
// NOTE: When you set dynamic true, make sure you give module a name
@Module({ dynamic: true, store: store, name: 'mm' })
class MyModule extends VuexModule {
  count = 0

  @Mutation
  incrCount(delta) {
    this.count += delta
  }
}

If you would like to preserve the state e.g when loading in the state from vuex-persist

...

-- @Module({ dynamic: true, store: store, name: 'mm' })
++ @Module({ dynamic: true, store: store, name: 'mm', preserveState: true })
class MyModule extends VuexModule {

...

Or when it doesn't have a initial state and you load the state from the localStorage

...

-- @Module({ dynamic: true, store: store, name: 'mm' })
++ @Module({ dynamic: true, store: store, name: 'mm', preserveState: localStorage.getItem('vuex') !== null })
class MyModule extends VuexModule {

...

Accessing modules with NuxtJS

There are many possible ways to construct your modules. Here is one way for drop-in use with NuxtJS (you simply need to add your modules to ~/utils/store-accessor.ts and then just import the modules from ~/store):

~/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 }

Now you can access stores in a type-safe way by doing the following from a component or page - no extra initialization required.

import { exampleStore } from '~/store'
...
someMethod() {
  return exampleStore.exampleGetter
}

Using the decorators with ServerSideRender

When SSR is involved the store is recreated on each request. Every time the module is accessed using getModule function the current store instance must be provided and the module must be manually registered to the root store modules

Example

// store/modules/MyStoreModule.ts
import { Module, VuexModule, Mutation } from 'vuex-module-decorators'

@Module({
  name: 'modules/MyStoreModule',
  namespaced: true,
  stateFactory: true,
})
export default class MyStoreModule extends VuexModule {
  public test: string = 'initial'

  @Mutation
  public setTest(val: string) {
    this.test = val
  }
}


// store/index.ts
import Vuex from 'vuex'
import MyStoreModule from '~/store/modules/MyStoreModule'

export function createStore() {
  return new Vuex.Store({
    modules: {
      MyStoreModule,
    }
  })
}

// components/Random.tsx
import { Component, Vue } from 'vue-property-decorator';
import { getModule } from 'vuex-module-decorators';
import MyStoreModule from '~/store/modules/MyStoreModule'

@Component
export default class extends Vue {
    public created() {
        const MyModuleInstance = getModule(MyStoreModule, this.$store);
        // Do stuff with module
        MyModuleInstance.setTest('random')
    }
}

Configuration

There is a global configuration object that can be used to set options across the whole module:

import { config } from 'vuex-module-decorators'
// Set rawError to true by default on all @Action decorators
config.rawError = true

More Repositories

1

vuex-persist

A Vuex plugin to persist the store. (Fully Typescript enabled)
TypeScript
1,655
star
2

SimpleFingerGestures_Android_Library

Android Library to implement simple touch/tap/swipe gestures
Java
315
star
3

android-locales

194
star
4

Android-SocialButtons

A library for easily implementing social login/share buttons
Java
150
star
5

awesome-jetbrains

A collection of awesome Fonts and Color Schemes to be used in Jetbrains IDEs.
88
star
6

awesome-devs

Everytime I come across good Github profiles I index them here
81
star
7

kernel-tools

tools to tinker with kernels and ramdisks and bootsplash images
C
78
star
8

NFC-host-card-emulation-Android

Testing bidirectional data transfer using NFC HCE on Android
Java
71
star
9

low-level-design-problem

Case studies (with solution codes) for Low Level System Design problems
Java
48
star
10

SPORK

Kotlin
48
star
11

GithubTrendingNow_Android

Kotlin
34
star
12

Navi_Imgur_App

Kotlin
34
star
13

InstaClone

Kotlin
21
star
14

yt_dlp_gui

Dart
20
star
15

vue-plugin-timers

TypeScript
16
star
16

Lifelog-Android-Library

An Android Library/API to access Sony Lifelog palatform.
Java
16
star
17

oh-my-zsh

Shell
14
star
18

ParkingLot-LLD-Kotlin-MPP

Kotlin
14
star
19

sharetime.in

Share your time, to anyone on any timezone
TypeScript
13
star
20

faangshaadi.com

HTML
12
star
21

hasgeek_mobile_nsvue

CSS
12
star
22

nativescript-vue-typescript-starter

Starter project for https://nativescript-vue.org using Typescript
JavaScript
12
star
23

express-ga-middleware

TypeScript
11
star
24

imguram

Kotlin
10
star
25

NFC-Bidirectional-over-HCE

Implementing bidirectional data transfer (half-duplex) using NFC HCE on Android
CSS
9
star
26

vscode-theme-quieter-dark

8
star
27

Conduit_SpringBoot_Postgres

Java
8
star
28

sharetime.zone

Share time in different timezones
Vue
7
star
29

authentication-authorization-20240717

6
star
30

SchoolTabApp

Java
6
star
31

LeetCodeByADev.js

Solving LeetCode using Dev-friendly JS Snippets
JavaScript
5
star
32

nativescript-awesome-webview

TypeScript
5
star
33

GoogleDrive_as_Datastore_Example

This project shows how you can use Google Drive as a datastore for your Android and Web apps
Java
5
star
34

Android-Tests-Example

An example repo showing how to setup unit tests and instrumentation tests on Android
Java
5
star
35

championswimmer

Github Profile Yay!
5
star
36

twitter-threads

5
star
37

GenericRecyclerAdapter

A RecyclerView Adapter that works with any type of Model(POJO)
Java
4
star
38

BadooTransactionApp

Java
4
star
39

Conduit_Flutter

Dart
4
star
40

parse-heroku-postgres

JavaScript
4
star
41

Kocktail_KMP_App

Kotlin
3
star
42

JavaConcurrencyExamples

Java
3
star
43

AlgorithmPractice

Java
3
star
44

guberx.io

HTML
3
star
45

qBounty-api-server

JavaScript
3
star
46

championswimmer.github.io

Championswimmer's About Page
CSS
3
star
47

express-universal-analytics

TypeScript
3
star
48

Xperia_FOTAKernel_Manager_Android_App

Java
3
star
49

wakanda-backend

TypeScript
3
star
50

spring-boot-taskmanager-demo

Java
3
star
51

Pyrrit

Simple python client for gerrit. To enable quick patchset listings, pushing and pulling.
Python
3
star
52

RealWorld-Spring-Kotlin

Kotlin
3
star
53

spring-boot-sockets-music

Java
3
star
54

GadiMeter

A live meter for many Indian cab and auto providers. Also provides fare estimates between two destinations.
Java
3
star
55

ns-vue-ts-sample

JavaScript
3
star
56

Learn_2_readwrite_files_Cpp

C++
2
star
57

design-patterns-sample-repo-java-tanmaykacker

Java
2
star
58

ember-parse-lib

JavaScript
2
star
59

oneauth

JavaScript
2
star
60

Flutter-PlatformWidgets-Sample

Dart
2
star
61

url-parser-workshop-typescript

TypeScript
2
star
62

InterComGeoDist

Kotlin
2
star
63

uri_parser_workshop_go

Go
2
star
64

InterviewQuestionsCpp

C++
2
star
65

vue-vuex-typescript-sample

CSS
2
star
66

conduit_flutter_riverpod

Dart
2
star
67

dukaan-backend

TypeScript
2
star
68

PCBuilderKT

Kotlin
2
star
69

realworld-vue3-pinia

Vue
2
star
70

AndroidWear_ComplicationProvider_Sample

Kotlin
2
star
71

AppDesk-NodeJS-Session-01

JavaScript
2
star
72

ember-parse-adapter-two

JavaScript
2
star
73

shitposting-bot

TypeScript
2
star
74

REST_API_Design_2024-03-16

2
star
75

Bookd_Android_App

Java
2
star
76

android_kernel_sony_msm8930

Sony Xperia L kernel source
C
2
star
77

nest-typeorm-sample

TypeScript
1
star
78

smolugger_rs

Rust
1
star
79

onepixel_backend

Go
1
star
80

words

words
1
star
81

Phonytale

Java
1
star
82

OverlayService

Java
1
star
83

URL_Shortner_Discord_Session

TypeScript
1
star
84

CollegeFests_Android_App

Java
1
star
85

new-vue-project

JavaScript
1
star
86

LeetCode-VSCode

TypeScript
1
star
87

india-aggregator-list

PHP
1
star
88

hashnode-backups

1
star
89

uses.page

TypeScript
1
star
90

ETHNYC2023-MonaWallpapers

Kotlin
1
star
91

fake-score-netlify-edge

TypeScript
1
star
92

ngbc-sample-march19-2

JavaScript
1
star
93

convert-radix64

JavaScript
1
star
94

cb-sample-heroku-app-02

JavaScript
1
star
95

ReFuel

Android App to keep track of fuel and mileage of your car
Java
1
star
96

IITD_Tryst_Android_App

Android App for Tryst
Java
1
star
97

android-drawable-converter

Automatically exported from code.google.com/p/android-drawable-converter
Java
1
star
98

simavr

C
1
star
99

sample-express-universal-analytics

TypeScript
1
star
100

WebNode2016Fall

HTML
1
star