How to manage the state in Vue 3 using Pinia

In any web application, effective state management is crucial for maintaining consistency and improving performance. As applications grow in complexity, managing the state becomes increasingly challenging. Vue.js, a popular JavaScript library known for its simplicity and flexibility, offers several options for state management in its latest version, Vue 3. Among these options is Pinia, a powerful and intuitive state management library. In this Answer, we will understand state management in Vue 3 using Pinia with a Rating App.

What is Pinia?

Pinia is a library that creates a centralized storage place for the Vue application; it allows sharing states across components.

Set up Store

  • The first step is to add Pinia dependency to our project package.json file. This can be done by running the following command in the terminal:

npm install pinia
# or
yarn add pinia
  • Now, we need to add Pinia service to the project. We can do this by adding the following code to main.js file:

import { createPinia } from 'pinia'
const pinia = createPinia()
app.use(pinia)
  • Now, we are good to go with Pinia. We need to create store for our application; we can do it by creating a folder with a name store in src folder. Create the store.js file inside the store folder. Add the following code boilerplate code to it:

import { defineStore } from 'pinia'
export const useStore = defineStore({
id: 'RatingApp',
state: () => ({
likes: 0
}),
actions: {
addlike() {
this.likes++;
},
unlike() {
this.likes--;
}},
getters:{
getRating: (state) => {
if(state.likes>10){
return 'Popular';
}else{
return 'Not Popular';
}
}
}
})

We need to add defineStore from pinia and create useStore (line 3) function. This function is used to access the store in the components. Before diving into the code, we need to understand state, actions, and getters:

The state

The state contains all the fields that need to be passed across multiple components. For example, in the code above (line 7), likes is a field that can be accessed in any child or parent component.

The actions

The actions are the methods that perform logic operations on the state field. These methods are used to interact with state variables. For example, in the above code (lines 10–16), we have two action methods addlike and unlike.

The getters

The getters are the aliases for computed method. It is used to access the compute side effect when state is changed. For example, in the above code (lines 18–26), it will return the rating as a string Popular or Not Popular based on the value of likes.

Using store

Now, we have created the Pinia store and can use it in the component. We need to import the useStore method that we created in the store:

<template>
{{store.likes}}
{{store.getRating}}
{{store.addlike}}
{{store.unlike}}
</template>
<script setup>
import { useStore } from "./store/store.js";
const store = useStore();
</script>

In the script tag, we need to import the useStore (line 8) method and initialize the constant store (line 9) to interact with store objects (e.g. actions, getters and state). We can access state, actions and getters by using a dot (.) operator (lines 2–5).

Test yourself

In the below playground, we have built the simple “Rating App.” It has two components and a Pinia store that contains the likes field. The state of likes can be changed from any component, and the updated state will be shared with all the components:

When we set the likes property in the “Change Rating” page by clicking “Increase likes” and “Decrease like,” it will maintain when we go back to the main “Rating App.”

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved