[Vue] 9. Vuex (상태관리)

22808 단어 vuevue

Vuex (상태관리)

vuex는 vue.js 어플리케이션을 위한 상태 관리 패턴 라이브러리이다.
모든 컴포넌트에서 접근해서 쓸 수 있는 중앙 저장소 역할을 한다. 단순히 데이터의 저장소 역할만 해주는 것이 아니라 데이터의 상태가 변경이 되면 변경사항이나 상태 변화를 처리할 수 있게 해준다.

vuex 설치하기

npm install vuex

vuex 사용하기

main.js와 같은 위치에 store.js 파일을 만든다.

store 안에 state를 통해서 변수를 선언하면 mutations 안에 있는 함수를 통해서만 변수에 접근할 수 있다.

// store.js
import { createStore } from "vuex";

const store = createStore({
  state() {
    return {
      count: 0,
    };
  },
  mutations: {
    increment(state) {
      state.count = state.count + 1;
    },
  },
});

export default store;

모든 컴포넌트에서 store를 쓸 수 있게 main.js에 코드를 추가해준다.

// main.js
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import mixins from "./mixins";
import store from "./store";
import VueSweetAlert2 from "vue-sweetalert2";
import "sweetalert2/dist/sweetalert2.min.css";
import i18nPlugin from "./plugins/i18n";

const i18nStrings = {
  en: {
    hi: "Hello!",
  },
  ko: {
    hi: "안녕하세요",
  },
};

const app = createApp(App);
app.use(router);
app.mixin(mixins);
app.use(VueSweetAlert2);
app.use(i18nPlugin, i18nStrings);
app.use(store);
app.mount("#app");

views 폴더 안에 StoreAccess.vue 파일을 만든다.

// StoreAccess.vue
<template>
  <div>
    <h2>Count: {{ count }}</h2>
    <button type="button" @click="increment">+1</button>
  </div>
</template>

<script>
export default {
  computed: {
    count() {
      return this.$store.state.count;
    },
  },
  methods: {
    increment() {
      this.$store.commit("increment");
    },
  },
};
</script>

<style scoped></style>

computed를 이용해서 store에 있는 count에서 변경사항이 일어나는지 감시하고 그걸 count라는 데이터 필드로 리턴해준다.

computed: {
    count() {
      return this.$store.state.count;
    },
  }

mutations에 정의된 함수를 호출하려면 반드시 commit이라는 함수를 사용해야 한다. commit 함수의 파라미터에 호출하려는 함수 이름을 전달해주면 된다.

this.$store.commit("increment");

store는 중앙 저장소이기 때문에 모든 컴포넌트에서 중앙 집중적으로 관리하고 싶은 것들을 store에서 관리하는 것이다. 그러므로 store에 있는 변수를 참조하고 있는 컴포넌트가 굉장히 많을 것이다. 그래서 변수에 변경이 일어났을 때 변경 상태를 관리해주고 다른 컴포넌트에 상태 변화를 전달해주기 위해서 mutations을 통해 함수를 정의하고 컴포넌트에서는 commit을 이용해서 접근하는 절차를 만들어둔 것이다. 즉, 상태관리를 체계적으로 하기 위해서 mutations를 통해서만 store에 있는 변수에 접근할 수 있도록 되어있는 것이다.
예를 들어, 사용자 로그인 정보를 store에 담아서 쓸 수 있다. 그리고 쇼핑 앱을 구현할 때 장바구니를 store에서 관리할 수 있다.

store 활용 예제 - 장바구니

state 안에 cart라는 배열을 선언해준다. getters를 사용해서 cart의 전체 요소 개수와 category가 A인 cart 요소 개수를 리턴해준다.
state에 있는 변수를 불러오는 건 그 변수 자체를 불러오는 것이다. getter 함수에 있는 함수를 불러오는 건 state에 정의된 변수를 getter 함수 안에 있는 함수에서 어떤 처리를 해준 후에 return하는 값을 불러오는 것이다.

// store.js
import { createStore } from "vuex";

const store = createStore({
  state() {
    return {
      count: 0,
      cart: [
        { product_id: 1, product_name: "아이폰 거치대", category: "A" },
        { product_id: 2, product_name: "블루투스 마우스", category: "B" },
      ],
    };
  },
  mutations: {
    increment(state) {
      state.count = state.count + 1;
    },
  },
  getters: {
    cartCount: (state) => {
      return state.cart.length;
    },
    productACount: (state) => {
      return state.cart.filter((p) => p.category == "A").length;
    },
  },
});

export default store;
// StoreAccess.vue
<template>
  <div>
    <h1>장바구니: {{ cartCount }}</h1>
    <h1>장바구니 - category가 A인 것만 : {{ productACount }}</h1>
    <h2>Count: {{ count }}</h2>
    <button type="button" @click="increment">+1</button>
  </div>
</template>

<script>
export default {
  computed: {
    count() {
      return this.$store.state.count;
    },
    cartCount() {
      return this.$store.getters.cartCount;
    },
    productACount() {
      return this.$store.getters.productACount;
    },
  },
  methods: {
    increment() {
      this.$store.commit("increment");
    },
  },
};
</script>

<style scoped></style>

좋은 웹페이지 즐겨찾기