DEV Community

Cover image for A comprehensive guide to pinia
Makanju Oluwafemi
Makanju Oluwafemi

Posted on • Edited on

A comprehensive guide to pinia

Originally published by me at miracool.hashnode.dev

Pinia is a new state management tool for vue js. It has been widely accepted within the vue js community due to its simplicity, efficiency, scalability, and flexibility. However, a lot of Vue developers still find themselves using Vuex due to limited information and a better understanding of the advantages of using pinia.

In this article, I will be explaining how a vue.js developer can quickly get the best out of Pinia by implementing an example app that features some of the use cases needed while working with Pinia. Readers interested in Vue JS will find this article very helpful, and an experienced Vue developer with knowledge of pinia will also build on their prior knowledge using this technology.

What is Pinia

Pinia is a state management solution that is based on the Vue JS concept of reactivity. In Vue JS, reactivity is a core feature that allows Vue JS to set up a remote tracking system for data that is reactive and automatically update the user interface when there is a change in these data properties.
Pinia builds on this core reactivity system by providing a way to manage the state of a Vue.js application in a reactive and efficient way. With Pinia, you can define a centralized store that holds all the state for your application and then use that store to manage your data and update the user interface as needed.
It offers a more effective, adaptable, and scalable approach to managing the state of your Vue.js applications in order to ease the process of maintaining application state. Pinia, which is based on the Composition API, has a number of advantages over more established state management programs like Vuex.
Pinia is compatible with both Vue 2 and Vue 3, so you don't have to trouble yourself with issues regarding versioning.

Let's get started with setting up Pinia Store in a fresh Vue.js application.

vue create pinia_tutorial
Enter fullscreen mode Exit fullscreen mode

Click enter to continue, and please follow the on-screen guide to complete the setup. Once completed, you will be prompted with these messages.

πŸŽ‰  Successfully created project pinia_tutorial.
πŸ‘‰  Get started with the following commands:
 cd pinia_tutorial
Enter fullscreen mode Exit fullscreen mode

CD to move into this new scalfold pinia_tutorial and run the next command to add pinia to the codebase.

vue add pinia
Enter fullscreen mode Exit fullscreen mode

Doing it this way will ensure that all the configurations needed for the store to function well will automatically be done for you, however, if you use yarn or npm to install it. You will have to manually do those configurations yourself.
There might be a file path error after the installation. Don't panic; just shut down the serve and rerun your npm run serve or yarn serve, depending on what you are using, and you should have a bug-free app.

Now, Let's do some real quick practical examples on creating and using the store.

store/index.js

import { defineStore } from "pinia";

export const useCounterStore = defineStore("counter", {
  state: () => ({
    count: 0,
  }),
  getters: {
    double: (state) => state.count,
  },
  actions: {
    increment() {
      //In vuex you will have to create a mutaion to do this directly
      //but, it's allowed here because pinia preaches flexibility
      this.count++;
    },
    decrement() {
      this.count--;
    },
  },
});

Enter fullscreen mode Exit fullscreen mode

From the usage of vuex, there should be states, mutations, getters, and actions, and you are not allowed to make changes to state data from within an action. To do that, you will have to create a mutation to update the data. Now the big deal is that pinia allows you to make changes to state data from within an action. Now the code above is a counter store that is defined to increment or decrease the count value;

Let's create a button in HelloWorld.vue so we can have a visual representation of what we are trying to achieve.

HelloWorld.vue


<template>
  <div class="hello">
    <h1>{{ count }}</h1>
    <button @click="incrementHandler" class="btn base-primary">
      Increment
    </button>
    <button @click="decrementHandler" class="btn base-primary">
      Decrement
    </button>
  </div>
</template>
Enter fullscreen mode Exit fullscreen mode

From the code snippet above, there are two buttons with a click event on each. Our aim is to create a click action that will eventually dispatch the actions in the Pinia store.

HelloWorld.vue


<script setup>
import { useCounterStore } from "../store";
import { computed } from "vue";

const store = useCounterStore();
const getCounter = computed(() => {
  return store.count;
});

const incrementHandler = () => {
  return store.increment();
};

const decrementHandler = () => {
  return store.decrement();
};
</script>
Enter fullscreen mode Exit fullscreen mode

In Pinia, stores are modules, so we have to import them before using them. reason why useCounterStore was imported and assigned to a new variable was ease of use. Instead of dispatching actions the vuex way, for example, $store.dispatch('action_name'). Pinia allows us to trigger the action directly with "store.increment," which is cleaner and better.

In conclusion, Pinia offers a robust and adaptable state management solution for Vue.js applications overall. It's a fantastic option for a variety of applications thanks to its straightforward API, flexible architecture, support for plugins, and support for custom stores. Pinia is unquestionably something to take into consideration if you're searching for a small and simple-to-use state management library for your Vue.js application.

Top comments (3)

Collapse
 
miracool profile image
Makanju Oluwafemi • Edited

Hey guys, this is my first article here. please like and follow

Collapse
 
wesleycheek profile image
Wesley Cheek

You don't actually need to have event handlers in your component just for calling your store actions. You can call the store actions directly inside the button: <button @click="store.increment">

Collapse
 
miracool profile image
Makanju Oluwafemi

Great!