ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 코딩 자율학습단(Vue.js 프런트엔드 개발 입문) 14일차
    정보교육/프런트엔드 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>
Designed by Tistory.