Pinia is now the officially recommended state manager for Vue 3. Earlier, Vuex was used officially. While Vuex still supports most of the Vue applications online, Pinia is the go-to state manager for building new apps.
Composition API comes with composables, which in one way can be used as a state manager as well. We don’t even need to install any package if we use composables. However, if we want a more standard, centralized, and optimized approach to managing states, Pinia is a better option. We get advanced debugging capabilities, DevTools support and a better view at how the states are communicating with each other. Earlier I’ve written an article on how we can manage states using composables.
In this article, we’ll have a look at how we can manage states using Pinia. We’re using the same example we used in composable in the previous article, but this time using Pinia. By doing that, we can also easily look at the differences between state management with composable vs state management with Pinia.
State management with Pinia
Make sure you have Pinia installed in your Vue 3 app. You can check your package.json file to confirm. If it’s missing, you can simply run the following command to install Pinia:
npm install pinia -s
Once installed, inside the src directory, we can now create a folder named stores. Inside stores, we’re creating a file named font.js.
The resultant path would look like src/stores/font.js
We can create multiple stores for multiple state management. Here, we’re creating a store to manage and control the font size.
Here’s the font.js file:
import { defineStore } from 'pinia'
export const useFontStore = defineStore({
id: 'font',
state: () => ({
fontSize: 16
}),
getters: {
isFontLarge: (state) => state.fontSize > 30
},
actions: {
increaseFontSize(amount) {
this.fontSize += amount
},
decreaseFontSize(amount) {
this.fontSize -= amount
},
resetFontSize() {
this.fontSize = 16
}
}
})
Code language: JavaScript (javascript)
If you’re familiar with Vuex, you’d immediately notice that we don’t have mutations anymore. Instead, we can now directly mutate a state value from the actions itself.
In the example above, we’re using state to declare initial states. We’re using getters to get some computed values from the store, which we may need somewhere. We finally have actions to define all the methods and their functionalities we can perform to update the states.
We can now use the above store in any component we want. Here’s a component using the useFontStore:
<script setup>
import { useFontStore } from '../stores/font'
const fontStore = useFontStore()
</script>
<template>
<div>
{{ fontStore.fontSize }}
<button @click="fontStore.increaseFontSize(4)">Increase font size</button>
<button @click="fontStore.decreaseFontSize(4)">Decrease font size</button>
<button @click="fontStore.resetFontSize()">Reset font size</button>
<div>
Is font large? {{ fontStore.isFontLarge ? 'Yes ✅' : 'No ❌' }}
</div>
<h1 :style="{ fontSize: `${fontStore.fontSize}px` }">My amazing heading</h1>
</div>
</template>
<style>
h1 {
font-family: Impact, Haettenschweiler, 'Arial Narrow Bold', sans-serif
}
</style>
Code language: HTML, XML (xml)
As we can see, we’ve imported the font store from stores on line 2. We’ve then defined the store state as fontStore. This fontStore state allows us to have complete access to the store. We can now get some value from the store directly. We can use a getter directly and we can even perform some actions directly.
Here’s what the above file would look like in action:
These were the basics of Pinia. If you have any doubts or suggestions, sound off in the comments below!