본문 바로가기
  • 일하면서 배운 내용 끄적이는 블로그
Vue

Vuex로 중앙에서 상태 관리하기

by dhl7799 2024. 5. 7.

Store

Vuex에서 store란 애플리케이션의 공유된 상태를 보유하고 있는 전역변수

상태(State), 뮤테이션(Mutations), 액션(Actions), 게터(Getters) 라는 속성(property)를 가지는데

애플리케이션 상태를 더 작은 모듈들로 나누어 구성하기 위해 모듈(Modules) 사용 가능

각각의 모듈들이 위 4가지 속성을 가짐

 

Store의 프로퍼티들

상태(State)

 

State는 Vue 컴포넌트에서 data이다 

원본 소스의 역할을 하며, View와 직접적으로 연결되어있는 Model이다. 

state는 직접적인 변경은 불가능하고 mutation을 통해서만 변경이 가능하다.

mutation을 통해 state가 변경이 일어나면 반응적으로 View가 업데이트된다.

뮤테이션(Mutations)

Mutation은 state를 변경하는 유일한 방법

이벤트와 유사하다. 

mutation은 함수로 구현되며 첫 번째 인자는 state를 받을 수 있으며, 두 번째 인자는 payload를 받을 수 있다. 

여기서 payload는 여러 필드를 포함할 수 있는 객체형태도 가능하다. 

이 mutation은 일반적으로(Helper를 쓰지 않는 경우)는 직접 호출을 할 수 없으며, commit을 통해서만 호출할 수 있다.
대부분 실무에서는 mutations에서는 API를 통해 전달받은 데이터의 가공하여 state를 설정하는 데 많이 사용된다

액션(Actions)

Action은 mutation과 비슷하지만 mutation과는 달리 비동기 작업이 가능. 

또한 mutation에 대한 commit이 가능하여 action에서도 mutation을 통해 state를 변경할 수 있다. 

action에서는 첫 번째 인자를 context 인자로 받고 이 context에는 state, commit, dispatch, rootstate와 같은 속성을 포함함. 

두 번째 인자는 mutation과 동일하게 payload로 받음

commit을 통해 mutation을 호출했다면 Action은 dispatch를 통해서 호출한다. 

context의 속성에 dispatch가 포함되어있어 action에서는 서로 다른 action을 호출할 수 있다.

실무에서 actions은 Axios를 통한 API 호출

그리고 그 결과에 대해서 반환(return)을 하거나 mutation으로 commit하여 상태를 변경하는 용도로 사용된다.

게터(Getters)

Getters는 쉽게 Vue 컴포넌트에서 Computed로 볼 수 있다. 

getter의 결과는 종속성에 따라 캐시 되고 일부 종속성이 변경된 경우에만 다시 재계산된다.

즉, 특정 state에 대해 어떠한 연산을 하고 그 결과를 View에 바인딩할 수 있으며, state의 변경 여부에 따라 getter는 재계산이 되고 View 역시 업데이트를 일으킨다.

이때 state는 원본 데이터로서 변경이 일어나지 않는다.

실무에서도 state의 연산 처리가 필요한 내용에 대해 getter를 사용하지만 getters의 경우 대용량 처리 시에 퍼포먼스와 연관이 되어있으므로 조심해야 한다. 

모듈(Modules)

큰 규모의 애플리케이션에서 상태를 더 작은 모듈로 나누어 구성할 수 있다.

모듈은 각각의 상태, 뮤테이션, 액션, 게터를 가질 수 있음.

네임스페이스(namespaced)

기본적으로 모듈 내의 action, mutation, getter는 전역 네임스페이스 아래에 등록된다.

여러 모듈의 mutation, action의 핸들러를 동일한 이름으로 만들었다면, 여러 모듈이 동일한 mutation 혹은 action에 반응하게 된다.

이때 namespaced: true를 사용하면 모듈이 독립적으로 재사용된다.

모듈이 등록 될 때, 해당 모듈의 모든 getter, action, mutation은 자동으로 모듈의 경로를 기반으로 네임스페이스가 지정되기 때문

사용 예시

App.vue

<template>
  <div id="app">
    <div v-if="isLoggedIn">
      <h1>Welcome, {{ user.name }}</h1>
      <button @click="logout">Logout</button>
    </div>
    <div v-else>
      <h1>Please login</h1>
      <button @click="login">Login</button>
    </div>
  </div>
</template>

<script>
export default {
  computed: {
    isLoggedIn() {
      return this.$store.getters['login/isLoggedIn'];
    },
    user() {
      return this.$store.getters['login/user'];
    }
  },
  methods: {
    login() {
      this.$store.dispatch('login/login', { name: 'John Doe' });
    },
    logout() {
      this.$store.dispatch('login/logout');
    }
  }
};
</script>

 

사용자의 로그인 상태에 따라 다른 메시지와 버튼을 표시하는 컴포넌트이다
computed 속성을 사용하여 Vuex 스토어의 login 모듈에서 상태를 가져오고
methods 속성을 사용하여 Vuex 스토어의 login 모듈의 액션을 디스패치한다
login: 사용자 로그인 액션을 호출
logout: 사용자 로그아웃 액션을 호출

main.js

import {store} from '~/vuex';
/*
	생략
*/

new Vue({
  el: '#app',
  router,
  store,
  i18n,
  render: h => h(App)
});

 

main.js 에서 Vuex 스토어를 Vue 인스턴스에 등록하면 애플리케이션 전체에서 Vuex를 사용할 수 있게 된다.

index.js

import Vue from 'vue';
import Vuex from 'vuex';
import loginModule from './modules/login';

Vue.use(Vuex);

const store = new Vuex.Store({
  modules: {
    login: loginModule
  }
});

export default store;

 

Vue.use(Vuex) 로 Vuex 플러그인 전역 설치

Vuex.Store를 설정하는 파일

loginModule을 모듈로 추가한다 

login.js

const state = {
  isLoggedIn: false,
  user: null
};

const mutations = {
  SET_LOGIN_STATUS(state, isLoggedIn) {
    state.isLoggedIn = isLoggedIn;
  },
  SET_USER(state, user) {
    state.user = user;
  }
};

const actions = {
  login({ commit }, userCredentials) {
    // 실제로는 API 요청 등의 비동기 작업이 이루어짐
    setTimeout(() => {
      commit('SET_LOGIN_STATUS', true);
      commit('SET_USER', userCredentials);
    }, 1000);
  },
  logout({ commit }) {
    commit('SET_LOGIN_STATUS', false);
    commit('SET_USER', null);
  }
};

const getters = {
  isLoggedIn: state => state.isLoggedIn,
  user: state => state.user
};

export default {
  namespaced: true,
  state,
  mutations,
  actions,
  getters
};

 

login 모듈을 정의(namespaced, state, mutations, actions, getters)

 

mutations

SET_LOGIN_STATUS: 사용자의 로그인 상태를 설정.
SET_USER: 사용자 정보를 설정

 

actions

login: 사용자 로그인을 처리

(여기서는 가짜 로그인을 가정하고 1초 후에 로그인 상태를 변경하고 사용자 정보를 저장)
logout: 사용자 로그아웃을 처리

 

getters
isLoggedIn: 사용자의 로그인 상태를 반환
user: 현재 로그인된 사용자의 정보를 반환

'Vue' 카테고리의 다른 글

디렉티브(Directives)  (0) 2024.05.08
Router push, replace, go  (0) 2024.05.08
Vue 프로젝트 경로의 @  (0) 2024.05.07
emit으로 자식 -> 부모 데이터 전달  (0) 2024.05.03
Vue 프로젝트 동작 순서  (0) 2024.05.02