window.pipedriveLeadboosterConfig = { base: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version: 2, } ;(function () { var w = window if (w.LeadBooster) { console.warn('LeadBooster already exists') } else { w.LeadBooster = { q: [], on: function (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: function (n) { this.q.push({ t: 't', n: n }) }, } } })() Vuex features you should know if you really care about your store - The Codest
The Codest
  • About us
  • Services
    • Software Development
      • Frontend Development
      • Backend Development
    • Staff Augmentation
      • Frontend Developers
      • Backend Developers
      • Data Engineers
      • Cloud Engineers
      • QA Engineers
      • Other
    • It Advisory
      • Audit & Consulting
  • Industries
    • Fintech & Banking
    • E-commerce
    • Adtech
    • Healthtech
    • Manufacturing
    • Logistics
    • Automotive
    • IOT
  • Value for
    • CEO
    • CTO
    • Delivery Manager
  • Our team
  • Case Studies
  • Know How
    • Blog
    • Meetups
    • Webinars
    • Resources
Careers Get in touch
  • About us
  • Services
    • Software Development
      • Frontend Development
      • Backend Development
    • Staff Augmentation
      • Frontend Developers
      • Backend Developers
      • Data Engineers
      • Cloud Engineers
      • QA Engineers
      • Other
    • It Advisory
      • Audit & Consulting
  • Value for
    • CEO
    • CTO
    • Delivery Manager
  • Our team
  • Case Studies
  • Know How
    • Blog
    • Meetups
    • Webinars
    • Resources
Careers Get in touch
Back arrow GO BACK
2020-07-21
Software Development

Vuex features you should know if you really care about your store

Wojciech Bak

Frontend applications, especially the more complex ones, have to process a lot of data. Programmers introduce various design patterns to make their projects readable and maintainable. In most the common scenarios of dealing with an MVC, we want to separate the data from the visual parts of the app.

That’s the reason why store has become so useful. It’s up to you whether you use React + Redux or Vue + Vuex – the main goal is the same, namely keeping your data structured, accessible and safe at the same time.

In this article, I’m going to show you a few examples of how to keep your Vuex store clean and efficient.

Before we start, let’s assume that:

  • you have some experience with modern JavaScript,
  • you basically know what Vue is and how to use props, computed, etc.,
  • you are familiar with Vuex (actions, mutations, etc.) and want to make your apps better.

Vuex, like the majority of core Vue projects, is pretty well-documented and you can find many useful hacks in official docs. We have extracted some essential information from it for you.

A basic Vuex store implementation looks like this:

// main.js

import Vue from 'vue'
import Vuex from 'vuex'
import App from "./App";

Vue.use(Vuex)

const store = new Vuex.Store((
  state: (
    data: null;
  ),
  actions: (
      someAction: (( commit ), data) (
          commit("SOME_MUTATION", data);
      )
  ),
  mutations: (
    SOME_MUTATION (state, data) (
        state.data = data;
    )
  ))
));

new Vue((
  el: "#app",
  render: h => h(App),
  store
));

Usually, when your app gets bigger, you have to apply routing, some global directives, plugins, etc. It makes the main.js file much longer and more difficult to read. It’s a good practice to keep the store in an external file, like here:

// store.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex);

const state = (
    data: null;
);

const actions = (
    someAction: (( commit ), data) (
        commit("SOME_MUTATION", data);
    )
);

const mutations = (
    SOME_MUTATION (state, data) (
        state.data = data;
    )
);

export default new Vuex.Store((
    state,
    actions,
    mutations
));

1. Modules

What should you do when the store.js file gets enormous and difficult to work on? Actually, there is a really cool Vuex feature – modules. They are dedicated to splitting your data into separate files.

Imagine that you work on some corporate app, in which you have few domains of data, for example:

  • user (manage all authorizations and permissions),
  • route parameters (manage global parameters before requests to API),
  • sales (for your SalesMegaChart component visible in a monthly/quarterly/yearly context),
  • orders (visible after clicking on the SalesMegaChart bar).

…and maybe a few more. Now you have serious reasons to introduce some modularity in your store.

First of all, move the store.js file to a newly created store/ directory and rename it index.js. Optionally, if you want to keep everything packed into modules, remove state, actions and mutations from the main file.

// store/index.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex);

export default new Vuex.Store((
    modules: (
        // modules will go here
    )
));

Then, next to the `store/index.js` file, create the first module – `store/user.js`.

import ApiService from '../services/api.service';

const state = (
    loggedIn: false,
    loginError: null,
    user: null
);

const actions = (
    login: async (( commit ), data) (
        try (
            const response = await ApiService.post('/login', data);
            const ( user ) = response.data;

            COMMIT("SAVE_USER", user);
            COMMIT("LOGIN_SUCCESS");
        ) catch (error) (
            commit("LOGIN_ERROR", error);
        )
    )
);

const mutations = (
    SAVE_USER (state, user) (
        state.user = user;
    ),

    LOGIN_SUCCESS (state) (
        state.loggedIn = true;
    ),

    LOGIN_ERROR (state, error) (
        state.loginError = error;
        state.loggedIn = false;
    )
);

export const user (
    state,
    actions,
    mutations
)

And now, load the ready module into the main `store/index.js` file:

import Vue from 'vue'
import Vuex from 'vuex'
import ( user ) from './user';

Vue.use(Vuex);

export default new Vuex.Store((
    modules: (
        user
    )
));

Congratulations! Now you have a really nice-looking store implementation. You can also access the data from the component (e.g., UserProfile.vue) like this:

<template>
    <div class="user-profile">
        <h2>(( user.name ))!</h2>
        <!-- component template goes here -->
    </div>
</template>

<script> import ( mapActions ) from 'Vuex';

    export default (
        name: 'UserProfile',

        computed: mapState((
            user: state => state.user
            // user: 'user' <-- alternative syntax
        ))
    )
</script>

2. Namespaces

Now that you know how to use modules, you should also become familiar with Vuex’s namespacing. On the previous step, we created the store/user.js file with the user module.

The data structure defined in the user.js file is accessible from components, but you can spot that all user data goes directly to the global state context, like here:

computed: mapState((
    user: state => state.user
    // user: 'user' <-- alternative way
))

When you define more modules, you’ll probably get confused about which object comes from which module. Then you should use namespaced modules and define them in this way:

export const user (
    namespaced: true, // <-- namespacing!
    state,
    actions,
    mutations
)

From now on, all your user data (state variable from store/user.js file) will be handled under the state.user reference:

computed: mapState((
    user: state => state.user.user
    // user: 'user/user' <-- alternative way
))

A few steps later, you can achieve for the component something like this:

import ( mapActions ) from 'Vuex';

export default (
    name: 'Dashboard',

    computed: mapState((
        sales: 'sales/data',
        orders: 'orders/data',
        sortBy: 'orders/sortBy',
        loggedIn: 'user/loggedIn'
    )),

    methods: mapActions((
        logout: 'user/logout',
        loadSales: 'sales/load',
        loadOrders: 'orders/load'
    )),

    created() (
        if (this.loggedIn) (
            loadSales();
            loadOrders();
        )
    )
)

Bravo! So fresh, so clean… But don’t worry, refactoring never ends. Ready for the next steps?

3. Communication between modules

In the first step, I you showed some action in the user module:

const actions = (
    login: async (( commit ), data) (
        try (
            const response = await ApiService.post('/login', data);
            const ( user ) = response.data;

            COMMIT("SAVE_USER", user);
            COMMIT("LOGIN_SUCCESS");
        ) catch (error) (
            commit("LOGIN_ERROR", error);
        )
    )
);

In case of failure, we’re adding login error to our store – what’s next?

Here we have a few options and the choice depends on which option suits your needs better. The simplest way used the v-if directive, thanks to which an error message can be displayed if there’s an error in your store.

<template>
    <div class="dashboard">
        <!-- dashboard component template -->
        <div
            v-if="error"
            class="error-message"
        > (( error.message )) </div>
    </div>
</template>
<script> import ( mapActions ) from 'Vuex';

export default (
    name: 'Dashboard',

    computed: mapState((
        error: "user/loginError"
    ))
)
</script>

Again, imagine that you have many modules and each try/catch syntax generates a new error in your store. Obviously, you’re going to abuse the DRY rule this way.

How can you make your error handling processes more generic?

Let’s define the common module and put some logic in there that would be used globally.

// store/common.js

const state = (
    errors: []
);

const actions = (
    error: (
        root: true,
        handler(( commit ), error) (
            commit("ERROR", error);
        )
    )
),

const mutations = (
    ERROR (state, error) (
        /* this way we're gonna have the newest error on top of the list */
        state.errors = [error, ...state.errors];
    ))
);

export const common (
    namespaced: true,
    state,
    mutations
)

Now, we can adapt the user module (and other modules as well):

try (
    // some action
)catch (error) (
    commit("common/ERROR", error, ( root: true ));
)

or in more elegant way, using our global action:

try (
    // some action
) catch (error) (
    dispatch("error", error);
)

This syntax of commit and dispatch calls seems self-explanatory, but you can read more about these tricks here.

When you have all errors in one place, you can easily load them to your Dashboard component:

computed: mapState((
    errors: 'common/errors'
)),

watch: (
    /* this will be invoked after each "common/ERROR" mutation, where we only add new errors to the store, one by one */
    errors() (
        this.showErrorMessage(this.errors[0]);
    )
)

The previous example with the common module handling errors is already an efficient solution, but you can go even further.

As you can see, we’re watching changes on the common/errors array in the store. In cases like these, when you need to determine some action on a particular mutation, you can use Vuex plugins or even Higher Order Components (HOC).

I will discuss the plugins and HOCs in the next article. Meanwhile, thank you for reading this entry, hopefully, you enjoyed the examples we’ve prepared.

Stay tuned and keep coding!

Read more:

– How to improve Vue.js apps? Some practical tips

– GraphQL: lessons learned in production

– Shopify, Spree or Solidus? Check why Ruby on Rails can help you develop your e-commerce

Related articles

Software Development

Build Future-Proof Web Apps: Insights from The Codest’s Expert Team

Discover how The Codest excels in creating scalable, interactive web applications with cutting-edge technologies, delivering seamless user experiences across all platforms. Learn how our expertise drives digital transformation and business...

THECODEST
Software Development

Top 10 Latvia-Based Software Development Companies

Learn about Latvia's top software development companies and their innovative solutions in our latest article. Discover how these tech leaders can help elevate your business.

thecodest
Enterprise & Scaleups Solutions

Java Software Development Essentials: A Guide to Outsourcing Successfully

Explore this essential guide on successfully outsourcing Java software development to enhance efficiency, access expertise, and drive project success with The Codest.

thecodest
Software Development

The Ultimate Guide to Outsourcing in Poland

The surge in outsourcing in Poland is driven by economic, educational, and technological advancements, fostering IT growth and a business-friendly climate.

TheCodest
Enterprise & Scaleups Solutions

The Complete Guide to IT Audit Tools and Techniques

IT audits ensure secure, efficient, and compliant systems. Learn more about their importance by reading the full article.

The Codest
Jakub Jakubowicz CTO & Co-Founder

Subscribe to our knowledge base and stay up to date on the expertise from the IT sector.

    About us

    The Codest – International software development company with tech hubs in Poland.

    United Kingdom - Headquarters

    • Office 303B, 182-184 High Street North E6 2JA
      London, England

    Poland - Local Tech Hubs

    • Fabryczna Office Park, Aleja
      Pokoju 18, 31-564 Kraków
    • Brain Embassy, Konstruktorska
      11, 02-673 Warsaw, Poland

      The Codest

    • Home
    • About us
    • Services
    • Case Studies
    • Know How
    • Careers
    • Dictionary

      Services

    • It Advisory
    • Software Development
    • Backend Development
    • Frontend Development
    • Staff Augmentation
    • Backend Developers
    • Cloud Engineers
    • Data Engineers
    • Other
    • QA Engineers

      Resources

    • Facts and Myths about Cooperating with External Software Development Partner
    • From the USA to Europe: Why do American startups decide to relocate to Europe
    • Tech Offshore Development Hubs Comparison: Tech Offshore Europe (Poland), ASEAN (Philippines), Eurasia (Turkey)
    • What are the top CTOs and CIOs Challenges?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Website terms of use

    Copyright © 2025 by The Codest. All rights reserved.

    en_USEnglish
    de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench pl_PLPolish arArabic it_ITItalian jaJapanese ko_KRKorean es_ESSpanish nl_NLDutch etEstonian elGreek en_USEnglish