Pinia는 이제 Vue의 공식 상태 라이브러리이다.
Pinia는 2019년에 composition API 로 vue store를 재설계 하기 위한 실험으로 시작되었다고 한다. vuex 공식문서에도 가보면 이제 vue의 공식 상태관리는 vuex가 아닌 pinia로 변경되었다고 써있다. pinia는 다른이름의 vuex5이고 그 전 버전들은 더 이상의 vuex의 새로운 기능 추가는 없다고 써있다.
이처럼 vue에서도 공식적으로 Pinia를 밀어주고 있는데
새로운 프로젝트를 계획하는 사람들에게는 Vuex보단 Pinia를 사용하는게 더 좋은 판단이라 보여진다.
또한 Vue에서도 React처럼 상태관리를 골라 쓸 수 있게 되었다.
우선 설치를 먼저 해본다.
npm install pinia
여기서 Vue2로 pinia를 설치 후에 Composition API 를 사용할 거라면 @vue/composition-api 설치가 필요하다.
설치가 완료되었다면 Vue에게 이 plugin을 쓸 것이라는 것을 언질(?)시켜줘야 한다.
import { createApp } from "vue";
import { createPinia } from "pinia";
import App from "./App.vue";
const app = createApp(App);
app.use(createPinia());
app.mount("#app");
여기까지 완료되었다면 Option Api를 사용할 지 Compsition Api를 사용할지를 고민해보자.
두 가지 선택지 중에 이 하나의 method로 인해 결정할 수 있는 것이 나눠진다.
바로, $reset() 이다.
$reset 은 option API에서만 지원이 가능하다.
$reset()은 특정 스토어의 상태를 초기화 시키는 것인데 상태관리에서는 데이터를 모든 컴포넌트에서 범용적으로 쓸 수 있기 때문에 데이터의 초기화를 시켜주는 것이 조금 더 데이터를 효율적으로 관리할 수 있다. 개인적으로 쓰는 것을 권장한다.
물론, Composition api를 쓴다고 해서 초기화를 못하는 것은 아니다. 다른 방법으로도 초기화가 가능하다. 다만, pinia에서 깔끔하게 $reset() 함수를 제공해주고 있기 때문에 이 같은 점을 고려해 꼭 초기화가 필요한 상태관리 설계를 해야 한다면 option api를 쓰는 것이 더 나은 선택일지 모른다.
지금 부터는 상태관리를 작성하는 방법에 대해 알아보자.
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
function increment() {
count.value++
}
const doubleCount = computed(() => count.value * 2)
return { count, increment, doubleCount }
})
여기서 잠깐 TIP 💡
Store의 명명규칙은 아래와 같다.
// You can name the return value ofdefineStore()
anything you want,
// but it's best to use the name of the store and surround it withuse
// andStore
(e.g.useUserStore
,useCartStore
,useProductStore
)
// the first argument is a unique id of the store across your application
export const useStore = defineStore('main', {
// other options...
})
요약해보면 use...store 이런식으로 네이밍을 가져라라는 뜻이다.
우리가 흔히 vuex에서 봤던 option api와는 사뭇 다른 모습이다. option api 에서 사용했던 getter, action 과 같은 문법이 아니다.
vue3의 composition api가 익숙치 않은 사용자들에겐 상당히 낯선 문법일 것이다.
다만, 앞에서도 말했듯이 vuex 보다 덜 형식적이고 간편하다는 뜻은 바로 action, mutations, getter등의 순서를 생각하지 않고 개발할 수 있다는 것이다.
기존에 vuex 문법에 익숙한 사용자라면 익숙할 것이다. 😉
// stores/counter.js
import { createVuex, defineStore } from 'vuex'
const vuex = createVuex()
const useCounterStore = defineStore({
key: 'counter',
state: () => ({
count: 1
}),
getters: {
double() {
return this.count * 2
}
},
actions: {
increment() {
this.count++
}
}
})
위와 같이 compotion api 를 사용하든 option api를 사용하든 store를 사용하는 vue 컴포넌트에서 사용하는 방법은 똑같다.
// App.vue
import { useCounter } from '@/stores/counter'
export default {
setup() {
const counter = useCounter()
return {
counter
}
}
}
저번 프로젝트에 vuex를 쓰고 이번 vue3프로젝트를 진행하면서 pinia도 도입해봤다.
확실히 getter, action 이런 거추장스러운(?) 관계를 생각하면서 작성한 것보다 vue3를 사용하면서 익숙하게 된 compsition api를 사용하는 것이 훨씬 간편했다.
오히려, 상태관리까지 composition api 문법을 사용하게 되면서 코드의 통일성이 더해졌다는게 개인적으로 좋았던 것 같다.😊