Vue3 Pinia

상태관리패턴?

복잡한 계층 구조의 컴포넌트들 사이에서 데이터를 공유해야할 때 props, emit 등을 사용하게되면 props drilling 문제나 유지보수에 있어 어려움이 발생하게 된다.
간단한 애플리케이션의 경우 reactivity api를 통해 수동으로 상태 관리 시스템을 만들 수도 있지만, 대규모 애플리케이션에서는 유지관리를 위해 Pinia라는 상태 관리 라이브러리를 사용하는 것이 권장된다.


Pinia?

현재 Vue3의 공식 상태관리 라이브러리로 컴포넌트/페이지 간에 상태를 공유할 수 있다.
이전 Vuex와 비교하여 더 간단한 API를 제공하고 Composition API 스타일의 API를 제공하며, Typescript와 함께 사용할 때 견고한 타입 추론을 지원한다.


✅ Pinia의 강점

  • Devtools 지원
    • actions를 추적하는 타임라인
    • Store는 사용되는 컴포넌트에 표시됨
    • Time travel과 쉬운 디버깅
  • Hot module replacement
    • 페이지 리로드 없이 store 수정
    • 개발하는 동안 기존 state 유지
  • Plugin : 플러그인으로 Pinia 기능 확장
  • Type Safe : Typescript 기반으로 Type에 대한 안정성 보장
  • 서버 사이드 렌더링 지원

Store란?
Store는 컴포넌트에 포함되지 않으며 전역적으로 사용되는 state 및 비즈니스 로직을 보유하고 있는 엔터티이다.
state, getter, action 3가지 개념이 있으며 이러한 개념은 data, computed, methods와 동일하다
Store에는 애플리케이션 전체에 접근할 수 있는 데이터가 포함되어야한다.


✅ Pinia 사용하기

Pinia 설치 및 등록

  • pinia 설치
npm install pinia
// or
yarn add pinia
  • vue3 pinia 등록
// main.js
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')

✅ Pinia 핵심 컨셉

1. Store 정의

  • Store라는 단위 안에서 상태 관리
  • defineStore 메소드를 통해 각 store의 유니크한 id와 옵션(state, getters, actions)를 정의한다. id는 필수이며 store를 devtools에 연결하는데 사용한다.
  • 생성한 store 객체는 use 키워드 + id + Store 키워드의 조합으로 이름을 붙여 export한다.



Options API
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0, name: 'ginger' }),
  getters: {
    doubleConunt: (state) => state.count * 2
  },
  actions: {
    increment () {
      this.count++
    }
  }
})


Setup API
  • ref : state 정의
  • computed : getters 정의
  • function : actions 정의
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  const name = ref('ginger')
  const doubleCount = computed(() => count.value * 2)
  function increment () {
    count.value++
  }

  return { count, name, doubleCount, increment }
})



2. Store 사용

import { useCounterStore } from '@/store/counter'

export default {
  setup () {
    const { name, doubleCount } = useCounterStore()

    return {
      name,
      doubleCount,
    }
  }
}

Categories:

Updated:

Leave a comment