Skip to content

How to add and use Vuex in a Vue 3 project

Creating new project

First we need to create a new Vue 3 project, we are going to use Vue CLI create command to create a new Vue 3 project, select Default options for Vue 3

vue create vue-3-vuex
cd vue-3-vuex

Installing npm modules

This is a list of all the packages needed and the reason why we will install them:

"vuex" (npm install vuex --save): Vuex is a state management pattern + library for Vue.js applications. It serves as a centralized store for all the components in an application, with rules ensuring that the state can only be mutated in a predictable fashion.
npm install vuex --save

Initializing project

Next we will initialize our application if everything was successfully you should see the Vue application on http://localhost:8080/

npm run serve

Creating store

First we are going to create a store with different modules, create a new folder called store inside the src folder, now create a folder called main inside our new store directory, this will be our main module we can create new modules by creating new folders with our module specific name, for example user, if we wanted to contain all user logic in a specific module. Each module will contain 5 files (actions.js, getters.js, index.js, mutations.js, state.js), in this case I'm going to show you an example of each file using our main Module

// src/store/main/state.js

// Will contain all the current values for the state of this module

let state = {
    pokemons: [], 
    message: "Pokemons module message"
};

export default state;
// src/store/main/getters.js

// Will contain getters to obtain the current values from the state variables in this module

let getters = {
    /**
     * Gets pokemon from state
     */
    POKEMONS: (state) => {
        return state.pokemons;
    },
    /**
     * Gets message from state
     */
    MESSAGE: (state) => {
        return state.message;
    },
};

export default getters;
// src/store/main/mutations.js

// Will contain all the mutations or functions that will alter the state of this module

let mutations = {
    /**
     * Sets pokemon state variable to the array received on payload results
     */
    SAVE_POKEMONS: (state, payload) => {
        state.pokemons = payload;
    },
};

export default mutations;
// src/store/main/actions.js

// Will contain  all actions of this module

let actions = {
    /**
     * Example action fetching Pokemons data and saving it on the state, using a mutation
     */
    GET_POKEMONS: (context) => {
        return new Promise((resolve, reject) => {
            fetch(`https://pokeapi.co/api/v2/pokemon?limit=150`)
                .then(response => response.json())
                .then(pokemons => {
                    context.commit("SAVE_POKEMONS", pokemons.results);
                    resolve(pokemons.results);
                }).catch((err) => {
                reject(err);
            });
        });
    },
};

export default actions;
// src/store/main/index.js

// Will export our module with all the actions, getters, mutations and the state

import actions from "./actions";
import getters from "./getters";
import mutations from "./mutations";
import state from "./state";

let main = {
    state,
    actions,
    mutations,
    getters,
};

export default main;

now we are going to export our store modules in the base file of our store

// src/store/index.js

// Will export all our modules

import Vuex from "vuex";

import main from "./main";

export default new Vuex.Store({
    modules: {
        main,
    },
});

Adding store to Vue App

Now search for the main.js file inside the src folder, this is the place where we will add our store to our Vue application

import { createApp } from 'vue'
import App from './App.vue'
// Import store entry file
import store from "./store";

const app = createApp(App);

// Tell created vue app to use our store with all it's modules
app.use(store);
app.mount("#app");

Interacting with the store on components

Now we can interact with our store in any Vue component, we will use the HelloWorld.vue component inside the components folder to display a list with the message in our main module and a list with the pokemons we got from our action

<template>
  <div class="hello">
    <h1>{{ message }}</h1>
  </div>

  <div class="pokemons-container">
      <ul>
          <li v-for="pokemon in pokemons" :key="pokemon.name">
              {{pokemon.name}}
          </li>
      </ul>
  </div>
</template>

<script>
// Import functions needed from vue
import { computed, onMounted } from "vue";
// Import composition API function to access store
import { useStore } from "vuex";

export default {
    // Component name
    name: "HelloWorld",

    // Composition API setup
    setup() {
        // Composition API function to access store
        const store = useStore();

        // Get message from store as computed property to trigger rendering on property changes
        let message = computed(() => store.getters["MESSAGE"]);

        /**
         * Get pokemons from store as computed property to trigger rendering on property changes
         * be carefull when having objects arrays inside of objects, computed properties won't trigger
         * rendering if one of the properties of an object of the array changes only if the whole array is
         * changed
         */
        let pokemons = computed(() => store.getters["POKEMONS"]);

        /**
         * @desc dispatch action to get pokemons from API
         */
        const getPokemons = async () => {
            // Dispatch GET_POKEMONS action without payload
           await store.dispatch("GET_POKEMONS", {});

            // Print value of pokemons in store
            console.log(pokemons.value)
        };

        /**
         * Run functionality on component mount
         */
        onMounted(() => {
            // Get pokemons
            getPokemons().then(() => {})
        });

        return {
            message,
            pokemons,
        };
    },
};
</script>

<style scoped>
</style>

GitHub repository

In this repository https://github.com/obravocedillo/Vue3Vuex you can find the code.