Vuex

Front-end Vue

Vue.js의 상태 관리를 위한 라이브러리.

상태 관리?

상태 관리란 여러 컴포넌트 간의 데이터 전달과 이벤트 통신을 한 곳에서 관리하는 패턴

상태 관리가 필요한 이유

컴포넌트 기반 프레임워크에서의 화면 요소간의 통신이나 데이터 전달을 좀 더 유기적으로 할 수 있도록 하기 위함. Vue의 props drilling, emit drilling(?) 방지 EventBus, mitt 라는 이벤트 에미터가 있지만 전자는 Vue에서 추천하는 공식적인 방법이 아니며 후자는 Vue에서 공식적으로 사용 가능하다는 말을 했으나 컴포넌트 간 데이터 흐름을 파악하기 어렵다. 공식적으로는 Vuex와 같은 상태 관리 라이브러리를 우선 추천하고 있다.

vuex example

상태 관리 패턴

상태 관리는 아래의 3가지로 구성된다.

  1. state : 컴포넌트 간 공유되는 data
  2. view : 데이터가 보여지는 template
  3. actions : 사용자의 입력에 따라 반응하는 methods
    new Vue({
      // state
      data() {
     return {
       counter: 0
     };
      },
      // view
      template: `
     <div></div>
      `,
      // actions
      methods: {
     increment() {
       this.counter++;
     }
      }
    });
    

State, View, Actions는 단방향 흐름 구조를 가진다. View 내부 인터랙션과 연관된 Actions를 통해 데이터를 변형하여 State에 저장하고, State에 저장된 데이터를 View에서 가져와 렌더하는 방식이다. vuex data flow example

Getters

여러 개의 컴포넌트에서 중복해서 사용되는 로직을 Vuex(store.js)에 저장하여 사용할 수 있다. Vuex의 state 변경을 각 컴포넌트에서 수행하지 않고 Vuex에서 수행하여 데이터를 변경한 후 컴포넌트에서는 로직만을 호출하도록 한다.

// store.js 
getters: {
  getSelectedMenu: function (state) {
    return state.selectedMenu;
  }
},

// Parent Component
computed: {
  selectedMenu() {
    return this.$store.getters.selectedMenu;
  }
},

// Child Component
computed: {
  selectedMenu() {
    return this.$store.getters.selectedMenu;
  }
},

Mutations

Mutation은 Vuex의 state를 변경하는 로직을 의미한다. Getters와는 아래의 방식에서 차이가 있다.

  1. Mutation은 인자를 받아서 store에 넘기게 된다.
    1. 주의할 점은 commit(state, payload)을 이용해서 이벤트를 호출한다는 것이다.
  2. computed가 아닌 methods에 등록된다.
// store.js
export const store = new Vuex.Store({
  // ...
  mutations: {
    selectMenu: function (state, payload) { // (state, payload)args를 받는다.
      state.selectedMenu = payload
    }
  }
});

// Component
methods: {
  selectMenu() {
    this.$store.commit('selectMenu', this.menu);
  }
},

Actions

Mutations와는 다르게 비동기 및 비순차적 로직을 선언한다.

// store.js
export const store = new Vuex.Store({
  actions: {
    getData: function (context) {
      return axios.get("list.json").then(function() {
        // ...
      });
    },
    selectMenuAfterDelay: function (context) {
      return setTimeout(function () {
        commit('selectMenu');
      }, 1000);
    }
  }
});

actions를 호출할 때는 dispatch(state, payload)을 이용한다.


참고
1 2