개발후라이
개발후라이
개발후라이
  • 분류 전체보기 (287)
    • Web Front End (76)
      • Javascript & Typescript (26)
      • React (12)
      • Vue (4)
      • Nodejs (1)
      • HTML (6)
      • CSS (8)
      • HTTP (6)
      • 책 - Review (8)
    • TIL (0)
    • Problem Solved (135)
      • 알고리즘 (4)
      • BOJ (67)
      • Programmers (8)
      • HackerRank (33)
      • LeetCode (23)
    • 회고 (4)
      • 오늘의 회고 (16)
      • 주간 회고 (15)
      • 월간 회고 (7)
      • WakaTime (9)
    • Git (3)
    • 기타 (15)
      • 취업 (5)
      • 자격증 (1)

블로그 메뉴

  • GitHub
  • LinkedIn
  • 홈

인기 글

태그

  • 개발자
  • 프론트엔드
  • 릿코드
  • 오늘의회고
  • JavaScript
  • 자바스크립트
  • TypeScript
  • 노개북
  • 노마드북클럽
  • 회고

최근 댓글

최근 글

전체 방문자
오늘
어제

티스토리

hELLO · Designed By 정상우.
개발후라이
Web Front End/Vue

Vuex로 상태관리하기

Vuex로 상태관리하기
Web Front End/Vue

Vuex로 상태관리하기

2020. 10. 27. 06:31
반응형

Vuex로 상태관리하기

컴포넌트 계층이 늘어나게 되면 props만으로 전달하거나 이벤트 버스만으로 해결되지 않는 상태 관리의 어려움이 생기게 됩니다.
이번 글에서는 이런 어려움을 해결한 Vuex 라이브러리의 패턴과 메소드를 알아 보도록 하겠습니다.

개요

  1. Vuex 아키텍처
  2. Store 영역
  3. Vue Component 영역

1. Vuex 아키텍처

Vuex는 데이터가 단방향 흐름으로 되어 있습니다. 이 흐름은 Flux 아키텍처와 비슷한 양상을 보입니다.

Vuex 아키텍처

vuex

Flux 아키텍처

flux

Vue 아키텍처의 흐름에 대해 설명하겠습니다.
먼저, Vuex의 Store에서 관리하는 부분은 Actions, Mutations, State입니다.
컴포넌트에서 Action이 일어나면 통신을 통해 값을 Mutation시킵니다. 그리고 그 결과를 받아 State가 변경되고 변경된 값을 컴포넌트에서 변경시킵니다.
설명으로는 간단해 보이지만 각각이 무슨 일을 하는지 와닿지 않을 수 있습니다. 밑에서 각각의 역할을 더 얘기하도록 하겠습니다.

2. Store 영역

Store는 new Vue.store({}) 로 생성하고, Vue.use(Vuex) 구문으로 전역에서 사용할 수 있습니다.

mutations

  • mutation은 변이입니다. 변이의 목적은 상태를 변경하는 것입니다.
  • 변이 안에서 상태 변경과 관련 없는 일(비동기적인 작업 등)은 Action에서 실행되도록 합니다. 즉, 동기적인 작업만 실행한다고 보면 됩니다.
  • Store는 state를 직접 변경하지 않기 때문에 반드시 변이를 통해서 변경해야 합니다.
  • DevTools에서는 변이 전후를 스냅샷 캡쳐해 디버깅을 제공합니다.
인자
  • 첫 번째 인자: state - 기존의 상태

  • 두 번째 인자: payload - 변이에서 필요로 하는 데이터. 즉 상태를 변경할 때 필요한 정보

    mutations: {
      save(state, userInfo) {
        state.id = userInfo.id;
        state.pw = userInfo.pw;
      }
    }

state

  • state는 애플리케이션에서 관리하는 중요한 데이터입니다. state는 변이를 통해서만 변경됩니다.
  • 초기값을 객체 형태로 지정하는 형태입니다.
  state: {
    id: "",
    pw: ""
  },

getters

  • Store에서 사용하는 computed 프로퍼티라고 할 수 있습니다. 즉, 필수는 아니지만 사용하면 편리함을 얻을 수 있습니다.
  • 여러 컴포넌트에서 사용하는 state일 경우, getters를 사용하면 코드의 중복을 줄일 수 있습니다.
  • 아래와 같이 자주 사용하게 되는 값을 getter 내부 메소드로 정의해 사용합니다.
getters: {
  currentId(state) {
    return state.currentId;
  }
}

actions

  • 외부 API를 실행하고 그 결과를 변이를 통해 전달해 상태를 변화시킵니다.
  • API를 호출하거나 비동기를 사용해야 할 경우가 없다면 생략해도 됩니다.
인자

변이는 state, payload를 전달하지만, 액션은 store, payload를 전달합니다. 액션 안에서 state, commit(), dispatch() 모두 사용할 수 있는 것입니다.

  • 첫 번째 인자: store
  • 두 번째 인자: payload
  actions: {
    incrementAsync ({ commit }, payload) {
      setTimeout(() => {
        commit('increment', payload)
      }, 1000)
    }
  }

namespace

  • Store 내의 actions, mutations, getters는 전역 namespace 아래로 등록됩니다. 여러 모듈에서 동일한 핸들러 이름을 사용한다면 여러 모듈에서 같은 반응을 하게 됩니다.
  • 독립적으로 사용하길 원한다면 namespace 옵션을 true로 설정해 사용하면 됩니다. true로 설정하면 경로 기반으로 namespace를 등록합니다.

3. Vue Component 영역

사용하기

사용할 컴포넌트 내부에서 this.$store로 Store를 접근하여 내부 메소드 사용 가능합니다.

  • state 접근: this.$store.state
  • mutation 접근: this.$store.commit('mutationName', payload)
  • getters 접근: this.$store.getters.currentId
  • actions 접근: this.$store.dispatch('save', payload)

헬퍼 메소드

위와 같이 사용하기 위해서는 this.$store를 계속 접근해야 하기 때문에 불편함이 있습니다.
이런 불편함을 줄이기 위한 컴포넌트 바인딩을 해 주는 메소드가 Vuex에 존재합니다.

mapState
  • Vuex의 상태는 컴포넌트의 computed 속성에 바인딩합니다. 그 이유는 컴포넌트 수준에서 상태를 직접 변경하지 않기 위함입니다. 직접 상태를 변경시킬 수 없게 하려면 Store의 속성 중 strict: true 옵션을 사용하면 됩니다.
  • 아래 비교 코드를 보겠습니다. 상태가 많아질 수록 위의 코드는 상태를 작성하기가 힘들어질 것입니다.
  computed: {
    id: this.$store.state.id,
    pw: this.$store.state.pw,
  }
  • state명을 배열로 하여 넣으면 state와 동일한 이름으로 값을 사용할 수 있습니다.
  • 이름을 바꿔야 한다면 Spread Operator를 사용해 다른 이름으로 가져옵니다.
  computed: mapState(['id', 'pw'])

  computed: {
    ...mapState({
      id2: state => state.id,
      pw2: state => state.pw
    })
  }
mapMutations
  • 변이를 동일한 이름의 메소드로 자동 연결되도록 해 줍니다.
  • 변이를 일으키지 않는 일반 메소드가 함께 있을 때는 Spread Operator를 사용합니다.
  • mapState와 동일하게 다른 이름으로 지정할 수 있습니다.
 methods: {
    updateUserInfo() {
      this.$store.commit("save", this.$data);
    },
    ...mapMutations(['save'])
 }
mapGetters
  • getters와 따로 이름을 설정하지 않으면 동일한 이름의 메소드로 연결됩니다.
computed: mapGetters(['currentId']),
mapActions
  • 컴포넌트에서 액션을 실행시키기 위해서는 dispatch 메소드를 사용해야 합니다. 그 이유는 _특정 객체에서 메소드를 호출하기 위해 메시지를 전달한다_는 의미가 있기 때문입니다.
methods: {
  ...mapActions(['save'])
}

참고

  • Vue.js 퀵 스타트
  • Vue.js 공식 사이트
  • [vuex] Modules
반응형
저작자표시 (새창열림)
  • 개요
  • 1. Vuex 아키텍처
  • 2. Store 영역
  • mutations
  • state
  • getters
  • actions
  • namespace
  • 3. Vue Component 영역
  • 사용하기
  • 헬퍼 메소드
  • 참고
'Web Front End/Vue' 카테고리의 다른 글
  • Vue에서 'Leave Site?'를 구현하는 3가지 방법
  • 회원가입 기능 만들며 React와 Vue 비교하기
  • [Vue 기초] Directive와 인스턴스 옵션
개발후라이
개발후라이
어제보다 오늘 발전하기 위한 공간 https://github.com/choisohyun

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.