본문 바로가기
프로그래밍

Vue3 상태 관리는 이제 Pinia로! Vuex 대체 라이브러리 Pinia 완벽 가이드

by 유형제맘 2025. 7. 29.

Vue3에서 상태 관리를 해야 할 때, 이제 더 이상 Vuex를 선택할 이유가 없습니다. Pinia는 Vue 공식 팀이 Vuex를 대체하기 위해 만든 새로운 상태 관리 도구로, 더 간결하고 타입 친화적인 문법을 제공하며 Composition API와도 잘 어울립니다.

Pinia란?

Pinia는 Vue3의 공식 상태 관리 라이브러리입니다. Vuex와 달리 mutations 없이도 상태를 변경할 수 있으며,
TypeScript 친화적이고 비동기 로직도 actions 안에서 자유롭게 처리할 수 있습니다.

1. 설치 및 기본 설정

npm install pinia

main.js 또는 main.ts에서 앱에 Pinia를 등록합니다.

// main.js
import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'

const app = createApp(App)
app.use(createPinia())
app.mount('#app')

2. 간단한 Store 만들기

Pinia의 스토어는 하나의 함수로 정의합니다. 보통 stores/ 폴더에 저장합니다.

// stores/counter.js
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0
  }),
  actions: {
    increment() {
      this.count++
    }
  }
})

3. Store 사용하기

<script setup>
import { useCounterStore } from '@/stores/counter'

const counter = useCounterStore()
</script>

<template>
  <div>
    <p>카운트: {{ counter.count }}</p>
    <button @click="counter.increment()">증가</button>
  </div>
</template>

ref나 reactive로 감싸지 않아도 자동으로 반응형입니다.

4. Computed와 Getter

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0
  }),
  getters: {
    doubleCount: (state) => state.count * 2
  }
})


<p>2배 수치: {{ counter.doubleCount }}</p>

5. 비동기 처리 (Actions에서 사용)

export const useTodoStore = defineStore('todo', {
  state: () => ({
    todos: []
  }),
  actions: {
    async fetchTodos() {
      const res = await fetch('https://jsonplaceholder.typicode.com/todos')
      this.todos = await res.json()
    }
  }
})

6. Setup 방식으로 정의 (Composition API 스타일)

// stores/user.js
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'

export const useUserStore = defineStore('user', () => {
  const name = ref('홍길동')
  const upperName = computed(() => name.value.toUpperCase())

  function updateName(newName) {
    name.value = newName
  }

  return { name, upperName, updateName }
})

Composition API를 선호한다면 이 방식이 더 유연하고 직관적일 수 있습니다.

7. Store 간 접근

Pinia에서는 다른 스토어도 쉽게 가져다 쓸 수 있어요.

import { useUserStore } from './user'

export const useDashboardStore = defineStore('dashboard', {
  actions: {
    greetUser() {
      const user = useUserStore()
      alert(`안녕하세요, ${user.name}`)
    }
  }
})

Pinia vs Vuex 비교

항목 Vuex Pinia
문법 스타일 복잡함 (state, getters, mutations, actions 분리) 간결함 (mutations 없음)
Composition API 지원 불편함 완전 호환
TypeScript 호환성 설정 복잡 우수
DevTools 통합 있음 Vue DevTools에 기본 포함
학습 곡선 높음 낮음

Pinia는 Vue3의 상태 관리를 훨씬 단순하고 깔끔하게 만들어 줍니다. Composition API, TypeScript, DevTools까지 모든 면에서 Vuex를 능가하며, 2025년 현재 기준으로 Vue3에서는 사실상 Pinia가 표준입니다. 이제 Vue3 프로젝트를 시작한다면 무조건 Pinia로 상태를 관리하는 것이 정답입니다.