Vue.js Pinia(state management lib)

17825 단어 vuevue

오늘은 피니아(pinia)를 가볍게 훑어보겠습니다.

https://pinia.vuejs.org/

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?

  • Devtools support
    - A timeline to track actions, mutations
    - Stores appear in components where they are used
    - Time travel and easier debugging
  • Hot module replacement
    - Modify your stores without reloading your page
    - Keep any existing state while developing
  • Plugins: extend Pinia features with plugins
  • Proper TypeScript support or autocompletion for JS users
  • Server Side Rendering Support

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 지옥에서 벗어날수 있다.
    문서 정리가 잘되어있으며, 내용도 어렵지 않아 러닝커브에 부담이 없다.

https://pinia.vuejs.org/

좋은 웹페이지 즐겨찾기