본문 바로가기
개발/Vue.js

Vue.js Vuex 알아보기

by 궁즉변 변즉통 통즉구 2022. 4. 8.
반응형

Vuex

  • vue에서 모든 컴포넌트가 접근 가능한 중앙 집중식 저장소 역할로 데이터 및 상태 관리를 할 수 있는 상태 관리 패턴 라이브러리
  • 데이터를 store에 저장하고, 프로젝트 전체에서 사용할 수 있음
  • 주로 사용자 로그인 정보, 쇼핑몰의 장바구니 정보 등 전역으로 관리되고 참조되어야 하는 정보들에 사용

출처: https://medium.com/dailyjs/mastering-vuex-zero-to-hero-e0ca1f421d45

Vuex Store 옵션

  • state: 프로젝트 전체에서 공통으로 사용할 변수 정의, state로 관리되는 데이터는 반응형
  • mutations: state에 정의된 변수를 변경할 수 있는 역할(동기처리), state의 변수를 직접 접근해서 변경은 불가
  • getters: state 변수의 로직처리 결과를 조회하는 Getter
  • actions: mutations과 비슷한 역할, 여러개의 mutations처리가 가능하고, 비동기처리(ex. API 통신호출)

 

Vuex Install

# stable 버전 설치
npm install vuex

# 가장 최신 버전 설치 방법
npm install vuex@next

 

Vuex Sample 코드

먼저 vuex의 store를 정의하는 파일을 /src/store.js로 아래와 같이 생성한다.

import { createStore } from "vuex";

const store = createStore({
  state() {
    return {
      count: 0,
    };
  },
  
  mutations: {
    increment(state) {
      state.count = state.count + 1;
    },
  },
  
  getters: {
    doubleCount: (state) => {
      return state.count * 2;
    },
  },
  
  actions: {  // 비동기 처리 로직에 사용
    incrementAction: (context) => {
      // return axios.get("url").then(...);
      return setTimeout(function () {
        context.commit("increment");
      }, 1000);
    },
  },
});

export default store;

 

다음으로 main.js에 store를 사용할 수 있도록 등록한다.

import store from "./store";

createApp(App)
  .use(router)
  .use(store) // store 등록
  .mount("#app");

 

Vuex를 테스트 해볼 컴포넌트를 아래와 같이 작성한다. 

<template>
  <div>
    <h2>Count: {{ count }}</h2>
    <h2>Double Count: {{ doublCount }}</h2>
    <button @click="click">Click</button>
    <button @click="actionCall">ActionCall</button>
  </div>
</template>
<script>
export default {
  setup() {},
  computed: {
    count() {
      // computed store 변수값을 추적 가능
      return this.$store.state.count;
    },
    doublCount() {
      // getters 호출
      return this.$store.getters.doubleCount;
    },
  },
  methods: {
    click() {
      // commit을 사용해서 store의 mutations 호출
      this.$store.commit("increment");
    },
    actionCall() {
      // dispatch를 사용해서 store의 actions 호출
      this.$store.dispatch("incrementAction");
    },
  },
};
</script>

기본적으로 state 변수 접근은 this.$store.state로 접근을 한다. state의 값을 computed()를 사용해서 계속 추적할 수 있다. "Click" 버튼 클릭 시 this.$store.commit('increment')메소드를 통해서 mutations에 선언한 increment로직을 수행하여 state변수의 값을 변경한다. getters 호출은 this.$store.getters를 통해서 가능하고 여기서는 state의 변수값 * 2를 결과를 리턴하게 했다. 마지막으로 "ActionCall"버튼 클릭 시 1초 뒤 값을 증가시키는 비동기 로직은 this.$store.dispatch를 통해서 호출한다.

 
참고로 위에 작성한 컴포넌트는 Vue3 Composition API setup()을 사용하여 아래와 같이 작성 할 수 있다.
<template>
  <div>
    <h2>Count: {{ count }}</h2>
    <h2>Double Count: {{ doublCount }}</h2>
    <button @click="click">Click</button>
    <button @click="actionCall">ActionCall</button>
  </div>
</template>

<script>
import { computed } from "vue";
import { useStore } from "vuex";

export default {
  setup() {
    const store = useStore();
    const count = computed(() => store.state.count); // store 변수값을 추적 가능
    const doublCount = computed(() => store.getters.doubleCount); // getter사용
    
    // commit을 사용해서 store의 mutations 호출
    const click = () => store.commit("increment"); 
    // dispatch를 사용해서 store의 actions 호출
    const actionCall = () => store.dispatch("incrementAction"); 
    
    return { count, doublCount, click, actionCall };
  },
};
</script>

 

vuex-persistedstate 플러그인

기본적으로 브라우저를 새로고침하게 되면 store에서 관리되고 있는 모든 데이터는 초기화가 된다. 이렇게되면 실제 어플리케이션 동작 상으로 문제될 수 있는데 vuex-persistedstate는 이를 방지하기 위한 플러그인이다.

 

vuex-persistedstate 설치

npm install  vuex-persistedstate

 

설치 후 위의 샘플에서 store.js에서 아래와 같이 plugins를 사용해서 화면 새로고침 시에 유지할 변수 값을 등록해준다.

import { createStore } from "vuex";

// vuex-persistedstate import
import persistedstate from "vuex-persistedstate";

const store = createStore({
  state() {
    return {
      count: 0,
    };
  },
  ....
  plugins: [
    persistedstate({
      paths: ["count"], // 화면 갱신 시 유지시킬 변수 등록
    }),
  ],
});

export default store;

 

다시 테스트 해보면 화면을 새로고침해도 값이 유지되는 것을 확인할 수 있다.

 

참고자료:

https://joshua1988.github.io/web-development/vuejs/vuex-start/

 

반응형

댓글