오늘은 피니아(pinia)를 가볍게 훑어보겠습니다.
The Vue Store that you will enjoy using
Vue 에서 사용하게될 스토어라고 소개가 되어있습니다.
Pinia started as an experiment to redesign what a Store for Vue could look like with the Composition API around November 2019. Since then, the initial principles are still the same, but Pinia works for both Vue 2 and Vue 3 and doesn't require you to use the composition API. The API is the same for both except for installation and SSR, and these docs are targeted to Vue 3 with notes about Vue 2 whenever necessary so it can be read by Vue 2 and Vue 3 users!
피니아는 2019년 11월경에 Store for Vue가 Composition API를 통해 어떤 모습을 보여줄 수 있는지를 재설계하기 위한 실험으로 시작되었습니다. 그 이후 초기 원리는 여전히 동일하지만 피니아는 Vue 2와 Vue 3 모두에서 작동하며 Composition API를 사용할 필요가 없습니다. API는 설치 및 SSR를 제외하고 동일하다고 설명이 되어있습니다.
Why should I use Pinia?
- A timeline to track actions, mutations
- Stores appear in components where they are used
- Time travel and easier debugging
- Modify your stores without reloading your page
- Keep any existing state while developing
devtools 지원
핫모듈 교체
플러그인을 통한 기능 확장
서버사이드 렌더링 지원
피니아에서는 왜 사용을 해야하냐라는 섹션을 제공해주고 위와 같이 간략하게 설명을 해주고 있습니다.
yarn add pinia
# or with npm
npm install pinia
main.js
import { createPinia } from "pinia";
import { createApp } from "vue";
import App from "./App.vue";
createApp(App).use(createPinia()).mount("#app");
main.js 에서 pinia 모듈에서 createPinia 를 import 하여, Vue3 Application Instance 에 use() 해준다.
이때 createPinia() 함수를 호출해야한다.
define store
import { defineStore } from "pinia";
// defineStore() 의 첫번째 인자는 스토어의 고유한 ID
export const useRootStore = defineStore("root", {
id: "root",
// state
state: () => ({
count: 0
}),
// getters
getters: {
getCount(state) {
return state.count;
},
getDoubleCount() {
// 다른 getter 를 참조
return this.getCount * 2;
}
},
// actions
actions: {
increaseCountAction() {
this.count++;
},
decreaseCountAciton() {
this.count--;
},
initCountAction() {
this.count = 0;
}
}
});
store 는 defineStore
를 활용하여 정의를 한다. vuex 에서는 root store 를 정의해서 모듈에 포함시켰던게 기억이 나지만, 피니아는 그런 수고를 덜 수 있다.
defineStore
를 활용하여 모듈단위로 스토어를 작성하면 그게 끝이다. vuex 에서 겪었던 namespace 문제도 더 이상 고민하지 않아도 된다.
defineStore
는 고유한 이름을 필요로 하는데, 이는 devTools 에 연결하는데 사용한다고 설명이 되어있다.
이렇게 정의한 스토어를 컴포넌트에서는 단순하게 import 하여 사용해주면 끝이다.
// example
// use store in component
import { useStore } from '@/stores/counter'
export default {
setup() {
const store = useStore();
// ❌ This won't work because it breaks reactivity
// it's the same as destructuring from `props`
const { count, increaseCountAction, decreaseCountAciton, initCountAction, getCount } = store;
return {
store,
}
},
}
정의한 스토어에서 instance 를 얻으면 getter, state, action 에 접근이 가능하다.
주의할점은 디스트럭쳐링은 불가능하다.
store 인스턴스 자체가 reactive 이기때문에 따로 처리를 안해줘도 된다.
꼭 구조분해할당을 하고자 한다면, import { storeToRefs } from 'pinia'
=> storeToRefs
를 활용하면 된다.
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<!-- <HelloWorld msg="Hello Vue 3 in CodeSandbox!" /> -->
<div>
<p>{{ store.getCount }}</p>
<p>{{ store.getDoubleCount }}</p>
<button @click="store.increaseCountAction">+</button>
<button @click="store.decreaseCountAciton">-</button>
<button @click="store.initCountAction">카운터 초기화</button>
</div>
</template>
<script>
// import HelloWorldVue from "./components/HelloWorld.vue";
// export default {
// name: "App",
// components: {
// HelloWorld: HelloWorldVue,
// },
// };
import { defineComponent } from "vue";
import { useRootStore } from "./store/index.js";
export default defineComponent({
name: "App",
setup() {
const store = useRootStore();
return {
store,
};
},
});
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
잘 동작을 한다.
그런데, 피니아는 mutation 이 존재하지 않는다?
피니아는 모든 상태관리 로직을 action 에서 관리 합니다.
문서를 살펴보면, 메서드와 동일하다라고 설명을 하고 있습니다.
그리고 만약 로직이 성공 또는 실패를 하면 원하는 무엇이든지 반환이 가능합니다.(메서드니까 당연)
getter 는 computed 와 동일하다라고 설명이 되어있습니다.
보통은 상태에만 의존을 하지만 원한다면 다른 getter 또는 매개변수에 의존하는 형태로도 사용이 가능합니다.
예제코드 : https://codesandbox.io/s/vue3-pinia-oi6tz
피니아는 기존 Vuex 와 비교하면 가볍게 사용이 가능하게 설계가 되어있다.
모듈단위로 작성해서 사용하기때문에 namespace 지옥에서 벗어날수 있다.
문서 정리가 잘되어있으며, 내용도 어렵지 않아 러닝커브에 부담이 없다.