본문 바로가기

Vue

[Vue] Pinia 의 활용법

1. 스토어 정의

import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', {
  state: () => ({
    name: '홍길동',
    age: 30
  }),
  getters: {
    isAdult: (state) => state.age >= 18
  },
  actions: {
    incrementAge() {
      this.age++
    }
  }
})

 


2. 컴포넌트에서 스토어 사용

<script setup>
import { useUserStore } from '@/stores/user'

const userStore = useUserStore()
</script>

<template>
  <div>
    <p>이름: {{ userStore.name }}</p>
    <p>나이: {{ userStore.age }}</p>
    <p>성인 여부: {{ userStore.isAdult }}</p>
    <button @click="userStore.incrementAge">나이 증가</button>
  </div>
</template>

 

 

3. 상태 변경

  • 직접 할당: userStore.name = '김철수'
  • 액션 사용: userStore.incrementAge()

 

 

4. 비동기 액션

actions: {
  async fetchUserData() {
    const response = await fetch('/api/user')
    const userData = await response.json()
    this.name = userData.name
    this.age = userData.age
  }
}

 

개인적으로 api 관련은 tanStack Query 사용을 추가하시는 것을 권장 드립니다.

 

5. 스토어 간 상호작용

import { useAuthStore } from './auth'

export const useUserStore = defineStore('user', {
  // ...
  actions: {
    async login(username, password) {
      const authStore = useAuthStore()
      await authStore.login(username, password)
      this.fetchUserData()
    }
  }
})

 

 

6. 상태 구독

 

상태 구독은 Pinia 스토어의 상태 변화를 감지하고 이에 반응할 수 있게 해주는 기능

  • $subscribe 메서드를 사용하여 구현하며
  • 상태가 변경될 때마다 콜백 함수가 호출됩니다.
  • 변경된 상태와 관련 정보를 받을 수 있습니다
const unsubscribe = userStore.$subscribe((mutation, state) => {
  console.log('상태 변경:', mutation, state)
})

// 구독 해제
unsubscribe()
const unsubscribe = userStore.$subscribe((mutation, state) => {
  console.log('변경된 상태:', mutation.type)
  console.log('새로운 상태:', state)
  
  // 특정 조건에 따른 로직 실행
  if (mutation.type === 'direct' && mutation.key === 'age') {
    console.log('나이가 변경되었습니다:', state.age)
  }
}, { detached: false })

 

  • detached: true로 설정하면 컴포넌트가 언마운트되어도 구독이 유지됩니다.
  • unsubscribe()를 호출하여 구독을 해제할 수 있습니다.

활용 방법

  • 상태 변화를 로깅하거나 디버깅할 때 유용합니다.
  • 특정 상태 변화에 따른 부가적인 로직을 실행할 수 있습니다.
  • 로컬 스토리지나 서버와의 동기화에 사용할 수 있습니다.

 

7. 스토어 리셋 ( 단 options API로 pinia 를 구성해야한다)

userStore.$reset()

 

 

8. 핫 모듈 교체 (HMR) 지원

개발 중에 애플리케이션을 다시 로드하지 않고도 모듈을 교체할 수 있게 해주는 기능

 

설정방법 

import { defineStore, acceptHMRUpdate } from 'pinia'

export const useUserStore = defineStore('user', {
  // 스토어 정의
})

if (import.meta.hot) {
  import.meta.hot.accept(acceptHMRUpdate(useUserStore, import.meta.hot))
}

 

  • 스토어 파일이 변경되면, Vite나 webpack과 같은 빌드 도구가 이를 감지합니다.
    •  현재 공식적으로 지원되는 번들은 Vite뿐이지만, import.meta.hot 사양을 구현하는 모든 번들러는 작동해야 합니다 (예외로 webpack은 import.meta.hot 대신 import.meta.webpackHot을 사용하는 것 같습니다)
  • acceptHMRUpdate 함수가 호출되어 스토어를 새로운 정의로 업데이트합니다.
  • 애플리케이션의 다른 부분은 그대로 유지되면서 스토어만 업데이트됩니다.

    https://pinia.vuejs.kr/cookbook/hot-module-replacement

 

9. 플러그인 사용

import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)

 

 

10. TypeScript 지원

export const useUserStore = defineStore('user', {
  state: () => ({
    name: '' as string,
    age: 0 as number
  }),
  // ...
})