Pinia 완벽 가이드 — Vue 3 공식 상태 관리 라이브러리
Pinia란?
Pinia는 Vue 3의 공식 상태 관리 라이브러리입니다. Vuex보다 훨씬 간결하고 TypeScript 지원이 뛰어납니다.
설치
npm install pinia
// main.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
createApp(App).use(createPinia()).mount('#app')
Store 정의 — Options Store
// stores/counter.js
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0,
name: 'Eduardo',
}),
getters: {
doubleCount: (state) => state.count * 2,
},
actions: {
increment() {
this.count++
},
async fetchUser(userId) {
const res = await fetch(`/api/users/${userId}`)
this.name = (await res.json()).name
},
},
})
Store 정의 — Setup Store (권장)
Composition API 스타일로 더 직관적입니다.
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
const doubleCount = computed(() => count.value * 2)
function increment() {
count.value++
}
return { count, doubleCount, increment }
})
컴포넌트에서 사용
<script setup>
import { useCounterStore } from '@/stores/counter'
const store = useCounterStore()
</script>
<template>
<p>Count: {{ store.count }}</p>
<p>Double: {{ store.doubleCount }}</p>
<button @click="store.increment">+1</button>
</template>
storeToRefs — 반응성 유지하며 구조 분해
import { storeToRefs } from 'pinia'
const store = useCounterStore()
// ❌ 반응성 깨짐
const { count } = store
// ✅ 반응성 유지
const { count, doubleCount } = storeToRefs(store)
// actions는 그냥 구조 분해해도 됩니다
const { increment } = store
스토어 초기화
store.$reset() // state를 초기값으로 되돌림
Vuex vs Pinia 비교
| 항목 | Vuex | Pinia |
|---|---|---|
| 보일러플레이트 | 많음 | 적음 |
| TypeScript | 복잡 | 자연스러움 |
| mutations | 필요 | 없음 |
| 모듈 | 네임스페이스 필요 | 스토어 파일로 분리 |
| Devtools | 지원 | 지원 |