Getting Started with Pinia: Installation, Store Creation, and Core Concepts
This guide introduces Pinia, a lightweight Vue state‑management library, covering its installation, creation of a Pinia instance, defining stores in both options and setup styles, and detailed usage of state, getters, and actions with code examples, highlighting its simplicity compared to Vuex.
Introduction
As a front‑end developer you know that state management is a crucial part of daily development. This article introduces Pinia, the new rising star in the Vue ecosystem.
What is Pinia
Pinia, like Vuex, is a state‑management library designed specifically for Vue. It lets you share state across components or pages, offers a simpler API than Vuex, and supports both Vue 2.x and Vue 3.x.
Installation
yarn add pinia // or using npm
npm install piniaCreating a Pinia Instance
Create a Pinia instance (the root store) and pass it to the Vue application:
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const pinia = createPinia()
const app = createApp(App)
app.use(pinia)
app.mount('#app')How to Create a Store
A Store (such as one created with Pinia) is an entity that holds state and business logic. It contains three concepts: State , Getter , and Action , analogous to a component’s Data , Computed , and Methods .
Create a store file src/stores/counter.ts :
// stores/counter.ts
// Options mode
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => {
return { count: 0 }
},
actions: {
increment() {
this.count++
},
},
})
// Setup mode
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
function increment() {
count.value++
}
return { count, increment }
})The first argument of defineStore is a unique ID that links the store to the devtools. The second argument can be either a setup function or an options object.
State
Using state in a component:
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore() <script>
// inside template
<div class="greetings">{{counter.count}}</div>
</script>Modify state directly or with $patch :
// Direct mutation
counter.count++
// Patch (can modify multiple properties)
counter.$patch({
count: counter.count + 1,
})Reset state to its initial value:
counter.$reset()Destructure state (note: loses reactivity unless using storeToRefs ):
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()
const { count } = counterPreserve reactivity with storeToRefs :
import { storeToRefs } from 'pinia'
const counter = useCounterStore()
const { count } = storeToRefs(counter)Getter
Getters are equivalent to computed properties of the store. They can access the whole store via this , other stores, and can return functions that accept parameters (these are not cached).
import { useOtherStore } from './other-store'
export const useCounterStore = defineStore('counter', {
state: () => ({ count: 0 }),
getters: {
// Simple computed getter
doubleCount(state) {
return state.count * 2
},
// Getter with explicit return type
doublePlusOne(): number {
return this.doubleCount + 1
},
// Access another store's getter
otherGetter(state) {
const otherStore = useOtherStore()
return state.count + otherStore.count
},
},
actions: {
increment() {
this.count++
},
},
})Action
Actions are similar to component methods; they can be asynchronous and can call other stores’ actions.
import { useAuthStore } from './user'
export const useCounterStore = defineStore('counter', {
state: () => ({ userInfo: {} }),
actions: {
async fetchUserInfo() {
const auth = useAuthStore()
if (auth.isAuthenticated) {
this.userInfo = await fetchUserInfo()
}
},
},
})Calling an action from a component:
<script setup>
const store = useCounterStore()
// Call the action as a method of the store
store.fetchUserInfo()
</script>
<template>
<button @click="store.fetchUserInfo()">Click Me</button>
</template>Conclusion
The above demonstrates the basic usage of Pinia. Compared with Vuex, Pinia’s API is much more concise: it drops mutations and modules, keeping only State, Getter, and Action, and its usage mirrors component Data , Computed , and Methods . It supports TypeScript and is extremely lightweight, with a bundle size of about 1 KB.
Reference
https://pinia.web3doc.top/
政采云技术
ZCY Technology Team (Zero), based in Hangzhou, is a growth-oriented team passionate about technology and craftsmanship. With around 500 members, we are building comprehensive engineering, project management, and talent development systems. We are committed to innovation and creating a cloud service ecosystem for government and enterprise procurement. We look forward to your joining us.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.