본문 바로가기
Vue

Pinia - Vuex 를 대체 할 수 있을까??

by Mishka 2022. 5. 16.

 Pinia  는 Vue의 새로운 상태 관리 라이브러리입니다.

Pinia 는 2019년 11월경 Composition API 를 사용하여 Store for Vue가 어떻게 생겼는지 재설계하기 위한 실험으로 시작되었습니다.

그 이후 초기 원칙은 동일하지만  Pinia 는 Vue2와 Vue3 모두에서 작동하며 Composition API 를 사용할 필요는 없습니다.

  • VueConf Toronton 2021 에서 Vue의 창시자 Evan You가 상태 관리 플러그인으로 vuex가 아닌 Pinia를 추천
Pinia([piːnjʌ] 영어로 "peenya" 로 발음됨) 는 유효한 패키지 이름인 piña(스페인어로 파인애플) 에 가장 가까운 단어입니다. 
파인애플은 실제로 여러개의 과일을 만들기 위해 결합된 개별 꽃의 그룹입니다. Store 와 마찬가지로 하나하나가 개별적으로 태어나지만 격국에는 모두 연결되어 있음을 의미합니다.

 

Pinia를 사용해야 하는 이유?

Pinia 는 Vue의 구성 요소/페이지 간에 상태를 공유할 수 있습니다.

Composition API 에 익숙하다면 아래와 같은 형태의 간단한 내보내기로 전역 상태를 공유 할수 있다고 생각 할 수 있습니다.

export const state = reative({})

이는 단일 페이지 애플리케이션에 해당하지만 서버 측에서 랜더링 되는 경우 애플리케이션을 보안 취약성에 노출 시킵니다.

그러나 작은 단일 페이지 어플리케이션에서도 Pinia 를 사용하면 많은 것을 얻을 수 있습니다.

 

Mutations 이 없습니다.

  • 상태변경을 위해 mutations 를 정의하고 commit 하는 과정이 필요없습니다.
  • vue 인스턴스의 state 값을 변경 할 때 처름 read/write 하면됩니다.

Typescipt 를 지원

  • Typescipt 를 통한 유형 추론을 최대한 활용할 수 있게 만들어져 있어서 복잡한 래핑을 하지 않아도 된다.
  • 타입을 별도로 지정해주지 않아도 타입 추론이 가능하다.

Namespace modules 없음

Devtools 지원

서버 측 렌더링 지원

 

Pinia 와 Vuex의 다른점

 Pinia  의 Store 선언 구문

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

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

Vuex 와의 가장 큰 차이점이라고 할 수 있는 것은   mutations  의 유무이다.

Vuex 에 존재하던  mutations  선언 필요 없이  actions  에서 값을 변화 시킬 수 있게 되었다.

 

사용할 때는 아래와 같은 형태로 사용한다.

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

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

    const onClickAdd = () => {
      // actions 를 직접선언
      counter.increment()
      // 이런식으로 Composition API 사용하는식으로 사용도 가능
      counter.count++
      // 내부 API 를 사용 가능하고 (with autocompletion ✨)
      counter.$patch({ count: counter.count + 1 })
      
    }
    
    return {
      onClickAdd,
      doubleValue: computed(() => counter.doubleCount),
    }
  }
}

 

위와 같이   Composition API  에서 사용형태와 비슷하며 쉽고 간편하게 Store 에 접근이 가능하다.

기존에  Vuex  에서 Store 정의하고  mutation ,  actions ,  getters   순서대로 작성하고  dispatch  를 이용하여 개발하던 것보다 훨씬 간편해졌다. 

 

만약 computed 선언을 하지 않고 구조분해할당을 하고 싶다면

// App.vue
import { useCounterStore } from '@/stores/counter'
import { storeToRefs } from 'pinia'

export default {
  setup() {
    const counter = useCounterStore()
    const { doubleCount } = storeToRefs(counter)

    const onClickAdd = () => {
      counter.count++
    }
    
    return {
      onClickAdd,
      doubleCount
    }
  }
}

위와 같이 하면 쉽고 간편하게 사용할 수 있다.

Vue3의 반응형 시스템 내부에서 구조분해할당을 사용하는 경우 반응형이 작동하지 않기 때문에 Vue3 에서 구조분해할당을 사용하시 위해 반응형 객체를 toRefs 로 묶어서 반응형을 유지할 수 있도록 지원한다.
참조

 

 Composition API  에 익숙 하다면 아래와 같은 형태로 사용할 수도 있다.

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

  return { count, increment, doubleCount }
})

 

마치며

기존 상태관리 라이브러리인 vuex 와 비교를 해보았을때 Pinia 가 매력적인 몇가지 사항들이 있는데, mutations 가 없어진 것과 Typescript 지원 그리고 devtools 의 공식 지원이다. 이번 새로운 프로젝트에 Pinia 도입 해서 사용해 보았는데 Composition API, Typescript 과의 궁합도 잘맞았다.

Vuex 와 동시 사용도 가능 하다고 하니 다들 한번 사용해 보시면 좋을것 같습니다.

 

 

참조
피니아 공식문서

Pinia - Vuex 를 대체할 새로운 Store!

Pinia

Pinia vs. Vuex: Which state management library is best for Vue?

티스토리 아이디로 코멘트를 남기려면

여기를 눌러주세요!

댓글0