반응형
| Pinia(피니아) | Vue.js의 공식 상태 관리 라이브러리(vue3) Pinia는 전역 상태(state)를 관리하는 도구로, Vue 컴포넌트 간 데이터를 공유할 수 있게 해줍니다. * 라우팅으로 상태관리가 어려워 피니아 사용 1. 피니어가 공유되면 초기화가 안되니 변수를 다르게 하거나, 매개변수를 분리 2. 파일은 js or 타입스크립트 가능 |
||
| 명명규칙 | 1. use + 파일명 + Store ex) useCounterStore 2. 고유값은 파일명과 같게 ex) defineStore( ' counter ', |
||
| 구조분해할당JS문법 | const store = { count: 5, name: 'Vue' } const { count, name } = store 동일 : const count = store.count, const name = store. name |
||
| storeToRefs | import { useCounterStore } from '@/stores/counter' const store = useCounterStore() watch(() => store.count, (newVal) => { console.log('store.count changed:', newVal) }) const { count } = store // > 구조가 분해됨. 최초이후 반응성 없음 watch(() => count, (newVal) => { console.log('count changed:', newVal) // ❌ 작동안함 }) import { useCounterStore } from '@/stores/counter' const store = useCounterStore() watch(() => store.count, (newVal) => { console.log('store.count changed:', newVal) }) const { count } = storeToRefs(store) //>구조분해 반응성 유지 watch(() => count, (newVal) => { console.log('count changed:', newVal) // ✅ 이제 count는 ref }) |
state, getters를 ref로 안전하게 추출 **actions 는 반응형이 아님 const { increment } = store |
|
| Option Store vs Setup Store : | |||
| Option Store | Vue2 : state, getters, actions 객체로 나눔 // stores/counter.js import { defineStore } from 'pinia' export const useCounterStore = defineStore('counter', { state: () => ({ count: 0, name: '피니아' }), getters: { doubleCount: (state) => state.count * 2 }, actions: { increment() { this.count++ } } }) ----------------------------------------------------- import { useCounterStore } from '@/stores/counter' const store = useCounterStore() const { count, name, doubleCount } = storeToRefs(store) // ✅ 반응형 유지 const { increment } = store // ✅ 메서드는 그냥 |
||
| Setup Store | Vue3 : ref, computed, function을 setup()처럼 사용 // stores/counter.js import { defineStore } from 'pinia' import { ref, computed } from 'vue' export const useCounterStore = defineStore('counter', () => { const count = ref(0) const name = ref('피니아') const doubleCount = computed(() => count.value * 2) function increment() { // this 사용안함 count.value++ } return { count, name, doubleCount, increment } }) -------------------------------------------- import { useCounterStore } from '@/stores/counter' const store = useCounterStore() // ✅ 모든 속성이 ref나 computed 이므로, 구조분해 바로 사용해도 반응형 유지 const { count, doubleCount, increment } = store |
||
| 기본구현 | main.js | import { createApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' const app = createApp(App) app.use(createPinia()) app.mount('#app') |
npm install pinia npm create vue@latest 사용시 여부 물어봄 |
| stores/counter.js src/ ├── main.js ├── App.vue ├── stores/ │ └── counter.js |
import { defineStore } from 'pinia' // 스토어 정의 export const useCounterStore = defineStore('counter', {// 이름 파일동일 state: () => ({ // data options 랑 같음 count: 0, name: '피니아' }), getters: { // computed options 랑 같음, status 에 매개변수전달 doubleCount: (state) => state.count * 2 }, actions: { //methods 같음, status this.로전달, 반응형아님 increment() { this.count++ }, async incrementLater() { await new Promise(resolve => setTimeout(resolve, 1000)) this.increment() } } }) |
||
| App.vue | <template> <div style="padding: 2rem"> <h1> Pinia 샘플</h1> <p>이름: {{ counter.name }}</p> <p>카운트: {{ counter.count }}</p> <p>2배 카운트: {{ counter.doubleCount }}</p> <button @click="counter.increment">+1</button> <button @click="counter.incrementLater">1초 후 +1</button> </div> </template> <script setup> import { useCounterStore } from './stores/counter' // 스토어 인스턴스 불러오기 const counter = useCounterStore() </script> |
||
'Web' 카테고리의 다른 글
| Vue.js - API 호출 정리 - Promise (3) | 2025.08.07 |
|---|---|
| [핵심만 골라 배우는 Vue.js by 수코딩] 11. 네트워크 - axios (액시오스), json-server (1) | 2025.08.05 |
| [핵심만 골라 배우는 Vue.js by 수코딩] 9. 라우팅 (1) | 2025.08.05 |
| [핵심만 골라 배우는 Vue.js by 수코딩] 8. Options API vs Composition API, 컴포저블 패턴 (0) | 2025.08.04 |
| [핵심만 골라 배우는 Vue.js by 수코딩] 7. 컴포넌트 심화- 상속, 동적렌더링 (1) | 2025.08.04 |