옹재
소소한 개발 블로그
옹재
전체 방문자
오늘
어제
  • 분류 전체보기 (66)
    • 개발 관련 서적 스터디 (6)
    • 프론트엔드 스터디 (36)
      • Javascript (16)
      • Typescript (13)
    • Vue 스터디 (22)
    • 개발 관련 스터디 (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • CSS
  • 개발서적 스터디
  • scss
  • 프론트엔드 스터디
  • 프레임워크 없는 프론트엔드 개발

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
옹재

소소한 개발 블로그

Vuex란?
Vue 스터디

Vuex란?

2021. 5. 19. 20:22
728x90
반응형

Vuex란?

  • 무수히 많은 컴포넌트의 데이터를 관리하기 위한 상태 관리 패턴이자 라이브러리
  • React의 Flux 패턴에서 기인함
  • Vue.js 중고급 개발자로 성장하기 위한 필수 관문

Flux란?

  • MVC 패턴의 복잡한 데이터 흐름 문제를 해결하는 개발 패턴 -Unidirectional data flow
  • 데이터 흐름이 한 방향으로 흐름 (단반향 통신) => Vue의 데이터 흐름을 보면 비슷하다.

  1. action : 화면에서 발생하는 이벤트 또는 사용자의 입력
  2. dispatcher : 데이터를 변경하는 방법, 메서드 (모델을 바꾸기 위한 방법)
  3. model : 화면에 표시할 데이터
  4. view : 사용자에게 비춰지는 화면

MVC 패턴 vs Flux 패턴 비교

MVC 패턴

Flux 패턴

MVC 패턴의 문제점

  • 기능 추가 및 변경에 따라 생기는 문제점을 예측할 수가 없음 ex) 페이스북 채팅 화면
  • 앱이 복잡해지면서 생기는 업데이트 루프

Flux 패턴의 단반향 데이터 흐름

  • 데이터의 흐름이 여러 갈래로 나뉘지 않고 단반향으로만 처리

Vuex가 왜 필요할까?

  • 복잡한 애플리케이션에서 컴포넌트의 개수가 많아지면 컴포넌트 간에 데이터 전달이 어려워진다.

이벤트 버스 해결?

  • 어디서 이벤트를 보냈는지 혹은 어디서 이벤트를 받았는지 알기 어려움
//Login.vue
eventBus.$emit('fetch', loginInfo);

//List.vue
eventBus.$on('display', data => this.displayOnScreen(data));

//Chart.vue
eventBus.$emit('refreshData', chartData);

컴포넌트 간 데이터 전달이 명시적이지 않음

Vuex로 해결할 수 있는 문제

  1. MVC 패턴에서 발생하는 구조적 오류
  2. 컴포넌트 간 데이터 전달 명시
  3. 여러 개의 컴포넌트에서 같은 데이터를 업데이트 할 때 동기화 문제

Vuex 컨셉

  • State : 컴포넌트 간에 공유하는 데이터 data()
  • View : 데이터를 표시하는 화면 template
  • Action : 사용자의 입력에 따라 데이터를 변경하는 method

Vuex 구조

컴포넌트 -> 비동기 로직 -> 동기로직 -> 상태

  1. 액션의 비동기 로직을 처리
  2. Mutations에서 동기로 State를 처리

Vuex 설치하기

  • Vuex는 싱글 파일 컴포넌트 체계에서 NPM 방식으로 라이브러리를 설치하는 게 좋다.
npm install vuex --save

Vuex 시작하기

  • src 폴더 밑에 store 폴더를 만들고 store.js 생성
import Vue from "vue";
import Vuex from "vuex";

//use : Vue의 플러그인
// vue에서 global로 사용할 것을 등록할 때 사용
Vue.use(Vuex);

export const store = new Vuex.Store({});

Vuex 기술 요소

  • state : 여러 컴포넌트에 공유되는 데이터 data
  • getters : 연산된 state 값을 접근하는 속성 computed
  • mutations : state 값을 변경하는 이벤트 로직, 메서드 methods
  • actions : 비동기 처리 로직을 선언하는 메서드 aysnc methods

State란?

  • 여러 컴포넌트 간에 공유할 데이터 - 데이터
//Vue
data : {
    message : 'hello'
}

//vuex
state : {
    message : 'hello'
}
<!-- vue -->
<p>
    {{message}}
</p>

<!-- vuex -->
<p>
    {{this.$store.state.message}}
</p>

getters란?

  • state ㄱ밧을 접근하는 속성이자 computed()처럼 미리 연산된 값을 접근하는 속성
//store.js
state : {
    num : 10
},
getters :{
    getNumber(state){
        return state.num;
    },
    doubleNumber(state){
        return state.num * 2;
    }
}
<p>{{this.$store.getters.getNumber}} </p>
<p>{{this.$store.getters.doubleNumber}} </p>

mutations란?

  • state의 값을 변경할 수 있는 유일한 방법이자 메서드
  • 뮤테이션은 commit()으로 동작시킨다.
//store.js
state : {
    num : 10,
},
mutations : {
    printNunbers(state){
        return state.num
    },
    sumNumbers(state, anotherNum){
        return state.num + anotherNum
    }
}

//App.vue
this.$store.commit('printNumbers');
this.$store.commit('sumNumbers', 20);

mutations의 commit()형식

  • state을 변경하기 위해 mutations를 동작시킬 때 인자(payload)를 전달할 수 있음
//store.js
state : {
    storeNum : 10,
},
mutations : {
    modifyState(state, payload){
        console.log(payload.str);
        return state.storeNum += payload.num;
    }
}

//App.vue
this.$store.commit('modifyState', {
    str : 'passed from payload',
    num : 20
})

state는 왜 직접 변경하지 않고 mutations로 변경할까?

  • 여러 개의 컴포넌트에서 아래와 같이 state 값을 변경하는 경우 어느 컴포넌트에서 해당 state를 변경했는지 추적하기가 어렵다.
methods : {
    increaseCounter() { this.$store.state.counter++;}
}
  • 특정 시점에 어떤 컴포넌트가 state를 접근하여 변경한 건지 확인하기 어렵기 때문
  • 따라서, 뷰의 반응성을 거스르지 않게 명시적으로 상태 변화를 수행. 반응성, 디버깅, 테스팅 혜택.

actions란?

  • 비동기 처리 로직을 선언하는 메서드. 비동기 로직을 담당하는 mutations
  • 데이터 요청, Promise, ES6 async와 같은 비동기 처리는 모두 actions에 선언
//store.js
state : {
    num : 10
},
mutataions : {
    doubleNumver(state){
        state.num*2;
    }
},
actions : {
    delayDoubleNumber(context){ //context로 store의 메서드와 속성 접근
        context.commit('doubleNumber');
    }
}

//App.vue
this.$store.dispatch('delayDoubleNumber');

actions 예제 1

//store.js
mutations : {
    addCounter(state){
        state.counter++;
    }
},
actions :{
    delayedAddCounter(context){
        setTimeout(() => context.commit('addCounter'), 2000);
    }
}

//App.vue
methods :{
    this.$store.dispatch('delayAddCounter');
}

actions 예제2

//store.js
mutations:{
    setData(state, fetchedData){
        state.product = fetchData;
    }
},
actions : {
    fetchProductData(context){
        return axios.get('https://domain.com/products/1')
                    .then(response => context.commit('setData', response));
    }
}

//App.vue
methods: {
    getProduct(){
        this.$store.dispatch('fetchProductData');
    }
}

왜 비동기 처리 로직은 actions에 선언해야 할까?

  • 언제 어느 컴포넌트에서 해당 state를 호출하고, 변경했는지 확인하기가 어려움

결론 : state 값의 변화를 추적하기 어렵기 때문에 mutations 속성에는 동기 처리 로직만 넣어야 한다.

728x90
반응형

'Vue 스터디' 카테고리의 다른 글

Nuxt.js 란?  (0) 2021.06.23
Vuex  (0) 2021.05.26
How the virtual DOM works in Vue.js  (0) 2021.05.10
Vue.js의 Virtual DOM이란?  (0) 2021.05.10
Vue.js의 Render 함수  (0) 2021.05.07
    'Vue 스터디' 카테고리의 다른 글
    • Nuxt.js 란?
    • Vuex
    • How the virtual DOM works in Vue.js
    • Vue.js의 Virtual DOM이란?
    옹재
    옹재

    티스토리툴바