반응형

0. 들어가기

-. state 관리 패키지인 pinia를 nuxt3에서 써보자.

-. 이전에는 vuex를 써왔는데, 거의 반 강제로 피니아로 변경하게 되었다.

1. 설치

-. pinia의 vue 3.2.45 버전에 대응이 아직 안되었는지 vue 버전이 맞지 않는다고 설치가 안되었다.

npm ERR! While resolving: undefined@undefined
npm ERR! Found: vue@3.2.45
npm ERR! node_modules/vue
npm ERR!   peer vue@"^3.2.45" from @nuxt/vite-builder@3.0.0
npm ERR!   node_modules/@nuxt/vite-builder
npm ERR!     @nuxt/vite-builder@"3.0.0" from nuxt@3.0.0
npm ERR!     node_modules/nuxt
npm ERR!       dev nuxt@"3.0.0" from the root project
npm ERR!   peer vue@">=2.7 || >=3" from @unhead/vue@1.0.13
npm ERR!   node_modules/@unhead/vue
npm ERR!     @unhead/vue@"^1.0.9" from @vueuse/head@1.0.22
npm ERR!     node_modules/@vueuse/head
npm ERR!       @vueuse/head@"^1.0.15" from nuxt@3.0.0
npm ERR!       node_modules/nuxt
npm ERR!         dev nuxt@"3.0.0" from the root project
npm ERR!   7 more (@vitejs/plugin-vue, @vitejs/plugin-vue-jsx, ...)

-. 버전 종속성을 무시하는 legacy-peer-deps 를 추가해야 설치가 된다.

npm install --legacy-peer-deps pinia @pinia/nuxt
{
  "devDependencies": {
    "nuxt": "3.0.0"
  },
  "dependencies": {
    "@pinia/nuxt": "^0.4.6",
    "pinia": "^2.0.28",
    ...
  }
}

-. 마지막으로, nuxt.config.ts 파일에 pinia module을 추가해야 실행 시 포함된다. 참고

export default defineNuxtConfig({
  modules: ["@pinia/nuxt"],
  ...
});

2. pinia 예제

1) store 작성

-. vuex와 동일하게, stores 폴더 내에 작성하면 되고, pinia store를 작성하는 방법엔 option storesetup stores가 있다. 
-. option stores는 기존 vuex와 유사한 방식으로, state, getters, actions의 세 부분으로 이루어진다. 각각 vue properties 중 data, computed, methods에 대응한다.

option stores
--
import { defineStore } from "pinia";

export const useOptionCounterStore = defineStore("option counter", {
  //data
  state: () => ({
    count: 0,
    name: "OptionCounterStore",
  }),
  //computed
  getters: {
    doubleCount: (state) => state.count * 2,
  },
  //methods
  actions: {
    increment() {
      this.count++;
    },
  },
});


-. setup stores는 composition API와 유사한 구조를 가진다. 

setup stores
--
import { defineStore } from "pinia";

export const useSetupCounterStore = defineStore("setup counter", () => {
  //define initial variables
  const count = ref(0);
  const name = ref("SetupCounterStore");
  //define computed variables
  const doubleCount = computed(() => count.value * 2);
  //define function
  function increment() {
    count.value++;
  }

  return { count, name, doubleCount, increment };
});

-. setup stores가 option stores보다 유연한 사용이 가능하다.. 는데, 난 뉴비라 사실 상세한 차이는 모르겠다. 다만, nuxt (SSR) 적용 시 복잡할 수 있으니, 잘 모르겠으면 option stores를 사용하라고 하더라. (아래 구문 참고.)

Setup stores bring a lot more flexibility than Option Stores as you can create watchers within a store and freely use any composable. However, keep in mind that using composables will get more complex when using SSR.
As with Vue's Composition API and Options API, pick the one that you feel the most comfortable with. If you're not sure, try Option Stores first.

2) store 호출 및 사용

-. composition API와 동일하게, vue의 setup에서 호출해서 사용할 수 있다. setup() 구문, 혹은 <script setup> 에서 호출하면 된다. nuxt 예제에는 전자로 적혀있지만, 난 후자가 편하니 <script setup>으로 사용.

<template>
  <v-container>
    <v-card elevation="5" @click="optionStore.increment()">
      <v-card-title> Option Stores </v-card-title>
      <v-card-subtitle> {{ optionStore.name }} </v-card-subtitle>
      <v-card-text>count: {{ optionStore.count }}</v-card-text>
      <v-card-text>double: {{ optionStore.doubleCount }}</v-card-text>
    </v-card>
    <v-card elevation="5" @click="setupStore.increment()">
      <v-card-title> Setup Stores </v-card-title>
      <v-card-subtitle> {{ setupStore.name }} </v-card-subtitle>
      <v-card-text>count: {{ setupStore.count }}</v-card-text>
      <v-card-text>double: {{ setupStore.doubleCount }}</v-card-text>
    </v-card>
  </v-container>
</template>

<script setup>
import { useOptionCounterStore } from "../stores/example_option";
import { useSetupCounterStore } from "../stores/example_setup";

const optionStore = useOptionCounterStore();
const setupStore = useSetupCounterStore();
</script>

-. option/setup stores 둘 다 정상 작동하는 것을 확인했다. 아마 난 option store를 사용할 것 같다.

3. 여러개의 store를 사용할 때,

-. 여러개의 store를 사용할 때 ~/stores/index.vue에서 관리해주면 좋다. 예를들어, 아래처럼 호출할 수 있다. 단 definestore의 "store name"은 다르게 지정해야함.

~/stores/index.vue
--
export * from "./example_option.js";
export * from "./example_setup.js";

----

example_option.js
--
export const useOptionCounterStore = defineStore("option counter", {
	...
});

----
example_setup.js
--
import { defineStore } from "pinia";

export const useSetupCounterStore = defineStore("setup counter", () => {
  ...
});

 

728x90
반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기