관리 메뉴

열심히 일한 당신 떠나라

코딩 자율학습단(Vue.js 프런트엔드 개발 입문) 14일차 본문

정보교육/프런트엔드

코딩 자율학습단(Vue.js 프런트엔드 개발 입문) 14일차

@thiskorea 2024. 7. 4. 09:47

9장 Pinia로 상태 관리하기
9.1 상태 관리란

상태(state): 웹 애플리케이션을 렌더링하는 과정에 영향을 줄 수 있는 값을 의미

상태관리: 이러한 값 관리

9.2 Pinia 사용 준비하기

pinia 설치

npm install pinia

pinia 인스턴스 생성 및 등록

import { createApp } from 'vue';
import { createPinia } from 'pinia'; // createPinia 함수 불러오기
import App from './App.vue';
import router from './router';
const app = createApp(App);
const pinia = createPinia(); // pinia 인스턴스 생성
app.use(router);
app.use(pinia); // pinia 인스턴스 등록
app.mount('#app');

스토어 생성

스토어: 애플리케이션의 상태를 중앙에서 관리하기 위한 Pinia의 독자적인 규격을 의미하는 용어

스토어 파일은 src/stores/ 폴더에 생성

스토어는 defineStore() 함수로 생성, 옵션 스토어와 셋업 스토어로 구분.

옵션 스토어

import { defineStore } from 'pinia';
export const useCountOptionStore = defineStore('countOption', {});

셋업 스토어

import { defineStore } from 'pinia';
export const useCountSetupStore = defineStore('countSetup', () => {
  // setup 문법
  return {};
});


9.3 Pinia 기본 문법 배우기

1 스테이트(state)

2 게터(getters)

3 액션(actions)

옵션 스토어

// vue.js.frontend/ch09_pinia/src/stores/countOption.js

import { defineStore } from "pinia";
export const useCountOptionStore = defineStore('countOption', {
    state() {
        return {
            num: 10,
            json: null,
        };
    },
    getters: {
        doubleNum(state) {
            return state.num * 2;
        },
        doubleNumPlusOne() {
            return this.doubleNum + 1;
        },
    },
    actions: {
        increment() {
            this.num++;
        },
        getJSON(url) {
            this.increment();
            fetch(url)
            .then((resonse)=>resonse.json())
            .then((json) => {
                this.json = json;
            });
        },
    },
});

셋업 스토어

// vue.js.frontend/ch09_pinia/src/stores/countSetup.js
import { defineStore } from 'pinia';
import { computed, ref } from 'vue';

export const useCountSetupStore = defineStore('countSetup', () => {
    const json = ref(null);
    const num = ref(10);
    const doubleNum = computed(()=>num.value * 2);
    const doubleNumPlusOne = computed(()=>doubleNum + 1);
    const increment = () => {
        num.value++;
    };
    const getJSON = (url) => {
        increment();
        fetch(url)
        .then((response) => response.json())
        .then((json) => {
            json.value = json;
        });
    };
    return {
        num,
        doubleNum,
        doubleNumPlusOne,
        json,
        increment,
        getJSON,
    };
});

컴포넌트에서 Pinia 사용하기

옵션스 API

<script>
import { mapState, mapActions } from 'pinia';
import { useCountOptionStore } from '@/stores/countOption';
import { useCountSetupStore } from '@/stores/countSetup';
export default {
  computed: {
    ...mapState(useCountOptionStore, ['num', 'doubleNum']), // this.num, this.doubleNum에 등록됨
    ...mapState(useCountSetupStore, {
      myNum: 'num', // 위와 같지만 this.myNum에 등록됨
      myDouble: 'doubleNum', // 위와 같지만 this.myDouble에 등록됨
    }),
  },
  methods: {
    // this.increment(), this.getJson()에 등록됨
    ...mapActions(useCountOptionStore, ['increment', 'getJSON']),
    ...mapActions(useCountSetupStore, {
      myIncre: 'increment', // 위와 같지만 this.myIncre()에 등록됨
      myJSON: 'getJSON', //위와 같지만 this.myJSON()에 등록됨
    }),
  },
};
</script>
<template>
  <h2>num: {{ num }}</h2>
  <h2>doubleNum: {{ doubleNum }}</h2>
  <button @click="increment">increment</button>
  <button @click="getJSON('https://jsonplaceholder.typicode.com/posts')">
    getJSON
  </button>
</template>

컴포지션 API

<script setup>
import { useCountOptionStore } from '@/stores/countOption';
import { useCountSetupStore } from '@/stores/countSetup';
import { storeToRefs } from 'pinia';
const optionStore = useCountOptionStore(); // 옵션 스토어 객체로 인스턴스 생성
const setupStore = useCountSetupStore(); // 셋업 스토어 객체로 인스턴스 생성
const { num, doubleNum } = storeToRefs(optionStore); // storeToRefs(setupStore)도 가능

// 객체에 접근하듯이 인스턴스로 스테이트, 게터, 액션 모두 일관되게 사용
console.log(optionStore.num); // 스테이트 num
console.log(setupStore.doubleNum); // 게터 doubleNum
optionStore.increment(); // 액션 increment
setupStore.getJSON('https://jsonplaceholder.typicode.com/posts'); // 액션 getJSON
console.log(num, doubleNum);
</script>
<template>
  <h2>num: {{ num }}</h2>
  <h2>doubleNum: {{ doubleNum }}</h2>
  <button @click="increment">increment</button>
  <button @click="getJSON('https://jsonplaceholder.typicode.com/posts')">
    getJSON
  </button>
</template>