🚀 Big News:Socket Has Acquired Secure Annex.Learn More
Socket
Book a DemoSign in
Socket

@averjs/vuex-decorators

Package Overview
Dependencies
Maintainers
2
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@averjs/vuex-decorators

Decorators for Vuex.

Source
npmnpm
Version
3.1.0
Version published
Weekly downloads
6
-89.09%
Maintainers
2
Weekly downloads
 
Created
Source

Vuex Decorators

Version Downloads CircleCi Codecov

Be aware that this package only supports Vuex Modules.

Thanks to Decorators in Typescript and Babel, we are able to transform the boring old way of writing Vuex into something way better.

Installation

To install the package use one of the following commands:

npm install @averjs/vuex-decorators
# OR
yarn add @averjs/vuex-decorators

If you want to use the type safe way you need to set the store in the config.

// the file where you initialize your vuex store

import { config } from '@averjs/vuex-decorators';
import Vuex from 'vuex';

const store = new Vuex.Store();
config.store = store;

Babel

In order for the Decorators and the classes to work, you need have a few babel plugins installed. Also keep in mind that if you want to use the @HasGetterAndMutation-Decorator for example, the babel plugins have to be >= 7.2.

  • @babel/plugin-proposal-class-properties
  • @babel/plugin-proposal-decorators

Typescript

To make this plugin work with Typescript the only thing you have to do is to enable experimentalDecorators in your tsconfig.json.

How it works

The best way of writing Vuex Modules with this package is to create a file for every module and export a class.

// MyNewAwesomeVuexModuleFile.js
export default class MyNewAwesomeVuexModuleFile {

}

Now in order for Vuex to understand what happens in the class you exported, you need to add a few Decorators. You can import them individually but the most important one is @VuexClass, because it initializes the module. The package is also built with Module Reuse in mind. That means that every module state is returning a function to avoid cross module pollution.

Every class also has to have a moduleName variable. This should be the identifier which you want to use in Vuex to access the module.

// MyNewAwesomeVuexModuleFile.js
import { VuexClass } from '@averjs/vuex-decorators';

@VuexClass
export default class MyNewAwesomeVuexModuleFile {
    moduleName = 'myAwesomeVuexModule';
}

Every function is getting called internally by using the call() method. That lets you call the states by using this. To keep calling dispatch and commit familiar with the typical vue notation, you can use this.$store inside your actions or getters. For Typescript there is a class called VuexModule, which you can import and extend from to provide you with typings for this.$store. You can find what can be called by this.$store by referring to the Vuex documentation.

// MyNewAwesomeVuexModuleFile.js
import { VuexClass, Action, HasGetterAndMutation, /* typescript */ VuexModule } from '@averjs/vuex-decorators';

@VuexClass
export default class MyNewAwesomeVuexModuleFile /* typescript */ extends VuexModule {
    moduleName = 'myAwesomeVuexModule';

    @HasGetterAndMutation variable = 'awesome';

    get getAwesomeVariable() {
        return this.variable;
    }

    set setAwesomeVariable(payload) {
        this.variable = payload;
    }

    @Action awesomeAction(test) {
        this.$store.commit('variable', test);
    }
}

Decorators

  • @VuexClass
  • @Getter
  • @HasGetter
  • @Mutation
  • @HasGetterAndMutation
  • @Action
  • @ExportVuexStore

Example

Vuex file

import { VuexClass, VuexModule, Action, Getter, Mutation, HasGetterAndMutation } from '@averjs/vuex-decorators';
import axios from 'axios';
import map from 'lodash/map';

@VuexClass
export default class TestStore extends VuexModule {
    moduleName = 'test';

    test = 'test';

    // generates getter
    get getTest() {
        return this.test;
    }

    // generates mutation
    set setTest(payload) {
        this.test = payload
    }

    // another way of defining a getter
    @Getter getterTest() {
        return this.test;
    }

    // another way of defining a mutation
    @Mutation mutationTest(payload) {
        this.test = payload;
    }

    @Action async fetchTest({ data }) {
        try {
            const { data: { test } } = await axios({
                url: `test`,
                method: 'GET',
                data
            });

            this.$store.commit('setTest', test);
        } catch (err) {
            throw err;
        }
    }
}

Type safety

When using the default way of accessing the vuex store, you never know eg. what type the getter returns or what payload the action accepts. Thats why we automatically create static properties on every vuex module you create which can be accessed by passing the store through the getModule method. If we take the store we described above, you can do something like this:

<template>
    <div>{{ test }}</div>
</template>

<script type="ts">
    import { Vue, Component } from 'vue-property-decorator';
    import TestStore from './TestStore';
    import { getModule } from '@averjs/vuex-decorators';

    const TestModule = getModule(TestStore);

    @Component
    export default class Test extends Vue {
        get test() {
            // old way
            return this.$store.getters['test/getTest'];

            // new way
            return TestModule.test;
            //  or
            return TestModule.getterTest;
        }

        set test(val) {
            // old way
            this.$store.commit('test/setTest', val);

            // new way
            TestModule.test = val;
            // or
            TestModule.mutationTest(val);
        }

        async callAction() {
            const data = new FormData();

            // old way
            await this.$store.dispatch('test/fetchTest', { data });

            // new way
            await TestModule.fetchTest({ data });
        }
    }
</script>

This feature is not limited to Typescript. It can also be used with Babel. Even though it will not give you precise typings, your IDEs intellisense will still tell you what can be called inside your vuex module.

Usage with Vuex

import Vuex from 'vuex';
import { ExportVuexStore } from '@averjs/vuex-decorators';
import VuexFile from './VuexFile.js';

const vuexFile = ExportVuexStore(VuexFile);

new Vuex.Store({
    modules: {
        [vuexFile.moduleName]: vuexFile
    }
});

Keywords

vue

FAQs

Package last updated on 20 May 2020

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts