본문 바로가기
IT/Pinia

Pinia

by 2T1 2022. 12. 30.
이 글은 Vue 3의 공식 Store | Pinia 를 보고 정리한 글입니다.
더 자세한 내용을 원하시면 공식 문서를 참고하세요.

시작하기

선호하는 패키지 관리자로 pinia를 설치합니다.

1
2
3
yarn add pinia
# or with npm
npm install pinia
cs
💡 TIP !
앱이 Vue 2.6.x 이하 버전을 사용하는 경우, 컴포지션 API도 설치해야 합니다: @vue/composition-api.
Nuxt를 사용하는 경우, 이 지침을 따라야 합니다.

 

main.js

@/main.js

1
2
3
4
5
6
7
8
9
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
 
const pinia = createPinia()
const app = createApp(App)
 
app.use(pinia)
app.mount('#app')
cs

 

 

⚠️ Vue 2를 사용하는 경우 플러그인을 설치하고 pinia앱의 루트에 생성된 파일을 삽입해야 합니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
import { createPinia, PiniaVuePlugin } from 'pinia'
 
Vue.use(PiniaVuePlugin)
const pinia = createPinia()
 
new Vue({
  el: '#app',
  // other options...
  // ...
  // note the same `pinia` instance can be used across multiple Vue apps on
  // the same page
  pinia,
})
cs

 

저장소에는 앱 전체에서 접근할 수 있으므로, 여러 곳에서 사용되는 데이터가 포함되어야 합니다.
(컴포넌트에서 호스팅할 수 있는 로컬 데이터를 스토어에서 포함하는 것은 피해야합니다.)


Store 정의

  • defineStore()를 사용하여 정의
  • 정의할 때, 고유한 이름이 첫번째 인자로 전달되어야 함
1
2
3
4
5
6
7
8
9
10
import { defineStore } from 'pinia'
 
// `defineStore()`의 반환 값(함수)을 할당할 변수의 이름은 원하는 대로 지정할 수 있지만,
// 스토어 이름을 사용하고 `use`와 `Store`로 묶는 것이 가장 좋습니다.
// 예: `useUserStore`, `useCartStore`, `useProductStore`
// 첫 번째 인자는 앱 전체에서 스토어의 고유 ID입니다.
 
export const useAlertsStore = defineStore('alerts', {
  // 다른 옵션...
})
cs

 

ID라고도 하는 이 name은 필요하며, Pinia에서 store와 devtools를 연결하는 데 사용합니다.

반환된 함수의 이름을 use...로 지정하는 것은, 사용법을 관용적으로 만들기 위한 컴포저블 전반에 걸친 규칙입니다.

 

defineStore()의 두 번째 인자는 두 개의 고유한 값을 허용합니다: 셋업 함수 또는 옵션 객체

 

 

option store

@/stores/counter.js

1
2
3
4
5
6
7
8
9
10
11
export const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0name'Eduardo' }),
  getters: {
    doubleCount: (state) => state.count * 2,
  },
  actions: {
    increment() {
      this.count++
    },
  },
})
cs

Vue의 옵션 API와 유사하게 state, actionsgetters 속성을 사용하여 옵션 객체를 전달할 수 있습니다.

 

 

setup store

@/stores/counter.js

1
2
3
4
5
6
7
8
9
10
export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  const name = ref('Eduardo')
  const doubleCount = computed(() => count.value * 2)
  function increment() {
    count.value++
  }
 
  return { count, name, doubleCount, increment }
})
cs

Setup Stores 에서는:

  • state 대신 ref()로 변수 선언
  • getters 대신 computed()로 전달
  • actions 대신 function() 사용
 💡 두가지 방식 중 가장 편한 것을 선택하면 됩니다.

 


Store 사용

setup() 내부에서 user...Store()가 호출될 때까지 스토어가 생성되지 않습니다.

@/src/apps/App.vue

1
2
3
4
5
6
7
8
9
10
11
12
import { useCounterStore } from '@/stores/counter'
 
export default {
  setup() {
    const store = useCounterStore()  // 스토어 정의
 
    return {
      // 템플릿에서 사용하기 위해 스토어 인스턴스를 반환할 수 있음
      store,
    }
  },
}
cs
💡 Tip ! setup 컴포넌트를 사용하지 않는 경우 map helper 로 pinia를 사용할 수 있습니다.

사용자가 원하는 만큼 스토어를 정의할 수 있습니다.
피니아를 최대로 활용하려면 각 스토어는 다른 파일에 정의해야 합니다.
(예: 번들이나 코드분할 및 TypeScript 추론을 자동으로 허용)

 

 

스토어 속성 추출

반응형을 유지하면서 스토어에서 속성을 추출하려면, storeToRefs() 를 사용합니다. 모든 반응형 속성에 대한 참조를 생성합니다.

스토어의 상태만 사용하고, 액션을 호출하지 않을 때 유용합니다. 스토어 자체에도 바인딩 되므로, 스토어에서 직접 액션을 구조화할 수 있습니다:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { storeToRefs } from 'pinia'
 
export default defineComponent({
  setup() {
    const store = useCounterStore()
    // `name`과 `doubleCount`는 반응형 refs임.
    // 이것은 플러그인에 의해 추가된 속성에 대한 'refs'도 생성함.
    // 그러나 모든 액션 또는 비반응형(ref/반응형이 아닌) 속성을 건너뜀.
    const { name, doubleCount } = storeToRefs(store)
    // increment 액션은 그냥 추출 가능.   
    // const { name, doubleCount } = store  => ❌ 이것은 반응형을 깨뜨리기 때문에 작동하지 않음.
    const { increment } = store
 
    return {
      name,
      doubleCount,
      increment,
    }
  },
})
cs

'IT > Pinia' 카테고리의 다른 글

Vue3 ) script setup  (0) 2023.03.28
Pinia - Action ( Option Store )  (0) 2023.01.02
Pinia - Getter ( Option Store )  (0) 2023.01.02
Pinia - State ( Option Store )  (0) 2023.01.02