이로

Vue3 상태관리도구 pinia / vuex / 등.. 본문

컴퓨터/Vue

Vue3 상태관리도구 pinia / vuex / 등..

利路 2024. 12. 2. 22:17
반응형

상태관리도구란

Vue 3에서 상태 관리 도구는 애플리케이션의 상태(데이터)를 중앙에서 관리하고 여러 컴포넌트에서 이를 효율적으로 공유하도록 돕는 도구를 말합니다. Vue.js는 컴포넌트 기반 구조이기 때문에 상태 관리가 중요하며, 복잡한 애플리케이션에서는 이를 잘 관리하기 위해 전용 상태 관리 도구를 사용하는 것이 일반적입니다.

Pinia 주요 특징

  • Pinia는 Vue.js의 공식 상태 관리 라이브러리
  • 모듈식 설계로 각 저장소(store)를 독립적으로 관리
  • TypeScript 지원이 우수하며 자동완성 기능 제공
  • Vue DevTools와 통합되어 디버깅이 용이
  • Composition API와 Options API 모두 지원

장점

  • 작은 번들 크기 (~1KB)
  • 직관적인 API로 학습곡선이 낮음
  • 저장소 간 상호작용이 쉬움
  • 비동기 작업 처리가 간편
  • 플러그인 시스템으로 확장성이 좋음

단점

  • 대규모 애플리케이션에서는 저장소 구조 설계가 복잡해질 수 있음
  • Vuex에 비해 커뮤니티 생태계가 상대적으로 작음

사용 추천 케이스

  • 중소규모 Vue3 프로젝트
  • TypeScript를 사용하는 프로젝트
  • 단순하고 유지보수가 쉬운 상태관리가 필요한 경우
  • 실시간 데이터 처리가 필요한 애플리케이션
// store/counter.js
import { defineStore } from 'pinia'

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

// component.vue
import { useCounterStore } from '@/stores/counter'

export default {
  setup() {
    const counter = useCounterStore()
    return { counter }
  }
}

 

vuex 주요 특징

  • 중앙 집중식 상태 관리 패턴
  • Mutations를 통한 동기적 상태 변경
  • Actions를 통한 비동기 작업 처리
  • State, Getters, Mutations, Actions로 구성
  • 모듈화를 통한 상태관리 분리

장점

  • Vue DevTools와 통합된 디버깅
  • 시간여행 디버깅 가능
  • 상태 변화 추적 용이
  • 모듈 시스템으로 확장성 우수
  • 강력한 미들웨어 지원

단점

  • 보일러플레이트 코드가 많음
  • TypeScript 지원이 제한적
  • 작은 프로젝트에선 과도한 복잡성
  • Composition API와 통합이 불편

사용 추천 케이스

  • 대규모 Vue 애플리케이션
  • 복잡한 상태 로직이 필요한 경우
  • 여러 컴포넌트간 상태 공유가 많은 경우
  • 상태 변화 추적이 중요한 프로젝트
// store/index.js
import { createStore } from 'vuex'

export default createStore({
  state() {
    return {
      count: 0,
      todos: []
    }
  },
  getters: {
    doubleCount: (state) => state.count * 2,
    completedTodos: (state) => {
      return state.todos.filter(todo => todo.completed)
    }
  },
  mutations: {
    INCREMENT(state) {
      state.count++
    },
    ADD_TODO(state, todo) {
      state.todos.push(todo)
    }
  },
  actions: {
    async fetchTodos({ commit }) {
      const response = await fetch('api/todos')
      const todos = await response.json()
      commit('SET_TODOS', todos)
    },
    increment({ commit }) {
      commit('INCREMENT')
    }
  },
  modules: {
    auth: {
      namespaced: true,
      state: { user: null },
      mutations: {
        SET_USER(state, user) {
          state.user = user
        }
      }
    }
  }
})

// Component.vue
export default {
  computed: {
    ...mapState(['count']),
    ...mapGetters(['doubleCount'])
  },
  methods: {
    ...mapActions(['increment']),
    handleClick() {
      this.increment()
    }
  }
}

 

 

반응형
Comments