프레임워크/Vue

[Vue] Vuex

은돌1113 2024. 4. 30. 12:35

0️⃣ 사용하는 이유

vue는 단방향 통신을 지원하는 프레임워크이기 때문에 부모에서 자식으로 props를 넘겨 데이터를 공유할 수는 있지만, 자식에서 부모로 데이터를 전송할 때는 $emit을 사용하는 방법이 있지만 이것은 권장하는 방식은 아니기 때문에 어려움이 있을 수 있고, 손자나, 형제에게 데이터를 공유할 때도 mitt 라이브러리를 사용할 수는 있지만 자주 사용하는 경우 코드가 복잡해지기 때문에 컴포넌트 간에 데이터를 많이 공유해야 하는 경우 중앙에서 일관성 있게 데이터를 유지하고, 공유하기 위해서 Vuex 상태 관리 라이브러리를 사용하면 좋습니다.👍

 

(※ 코드가 길어질 수 있기 때문에 데이터를 공유해야 하는 컴포넌트가 많거나, 대규모 프로젝트에서 데이터를 다뤄야 할 때 vuex를 사용하는 것이 좋습니다.)


1️⃣ 설치 및 세팅

$ npm install vuex
$ yarn add vuex

 

  1. src > store 폴더 생성 > store.js 생성
    import { createStore } from "vuex";
    
    const store = createStore({
        state() {
            return {
                count: 0
            }
        },
        mutations: {
            increment(state) {
                state.count++
            }
        }
    })
    
    export default store​
  2. main.js 세팅
    import App from './App.vue'
    import store from './store/store';
    
    createApp(App).use(store);​
    .use(store)를 사용하면 전역에서 store 상태를 공유할 수 있습니다.

2️⃣ 사용

<template>
  <p>{{ $store.state.count }}</p>
</template>

...생략

 

 

 

🙅‍♀️ : vuex에서 state 값을 수정하고 싶을 때는 아래 예시와 같이 직접적으로 state의 값을 변경하면 안 됩니다.

<button @click="$store.state.count++">+</button>

 

🙆‍♀️ : vuex에서 state 값을 수정하고 싶을 때는 아래와 같은 과정을 거쳐야 합니다.

 

1️⃣ $store.commit()를 사용해서 state를 변경하는 경우

  • store에 mutation을 정의한다. (state를 변경하는 로직을 담고 있는 함수)
  • $store.commit('함수 이름')을 사용해서 해당 mutation을 호출한다.
import { createStore } from "vuex";

const store = createStore({
    state() {
        return {
            count: 0
        }
    },
    mutations: {
        increment(state) {
            state.count++
        },
        decrement(state, payload) {
            state.count -= payload
        }
    }
})

export default store
<template>
  <h4>현재 count는 {{ $store.state.count }}입니다.</h4>
  <button @click="$store.commit('increment'">+</button>
  <button @click="$store.commit('decrement', 5)">-</button>
</template>

... 생략

 

 

2️⃣ actions를 사용해서 mutation을 호출하는 경우

: 주로 ajax 요청을 해야 할 때 actions에서 데이터 요청 후 mutation을 호출하여 state를 변경합니다.

  • state를 변경하고 싶은 경우 actions에 있는 action을 호출한다.
  • action은 필요한 로직을 실행한 후에 state를 변경하기 위한 mutation을 호출한다.
  • mutation은 실제 state 값을 변경한다.
import { getData } from "@/hooks/getData";
import { createStore } from "vuex";

const store = createStore({
    state() {
        return {
            data: {}
        }
    },
    mutations: {
        setData(state, payload) {
            state.more = payload
        }
    },
    actions: {
        async getData() {
            const data = await getData();

            if (data) {
                this.commit("setData", data)
            } else {
                alert("데이터가 없습니다.");
            }
        },
        
        or
        
        async getData(context) {
            const data = await getData();

            if (data) {
                context.commit("setData", data)
            } else {
                alert("데이터가 없습니다.");
            }
        }
    }
})

export default store
<template>
  {{ $store.state.data }}
  <button @click="$store.dispatch('getData')">데이터 가져오기</button>
</template>