plogger

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 비교

항목VuexPinia
보일러플레이트많음적음
TypeScript복잡자연스러움
mutations필요없음
모듈네임스페이스 필요스토어 파일로 분리
Devtools지원지원