Vuex

  • Vue에서 쓰는 상태 관리 라이브러리
  • 컴포넌트가 엄청 많아졌을 때, 관리를 조금 더 쉽게 할 수 있음!
  • Vuex Helper로 더 쉽게 vuex를 코딩하자.
  • Vuex로 프로젝트 구조화 및 모듈 구조화하자.
  • Vuex의 주요 속성 state, getters, mutations, actions 학습

Vuew에 영향을 준 Flux란?

  • 페이스북에서 설계한 아키텍처
  • MVC 패턴의 복잡한 데이터 흐름 문제를 해결하는 개발 패턴
    • 단방향 데이터 흐름으로 전환하여 흐름이 복잡해지는 문제를 예방
  • action -> Dispatcher -> Model -> View
    • action : 화면에서 발생하는 이벤트 또는 사용자 입력
    • dispatcher : 데이터를 변경하는 방법, 메서드
    • model : 화면에 표시할 데이터
    • view : 사용자에게 비춰지는 화면
  • MVC 패턴이랑 비교
    • ( 나는 지금 흐름이랑 너무 멀구나~ )
    • 여러 View에서 다양한 Model을 요청하고 Model은 다양한 View에 변화를 주니... 데이터 흐름을 파악은 불가능...

Vuew의 필요성

  • 컴포넌트가 많아지면 컴포넌트와 컴포넌트 사이의 프로퍼티 전달이 번거롭고 고치기 어려움
  • 이벤트 버스를 이용하여도 어디서 발생한 이벤트인지 파악하기 힘들다.
    • "XX" 이름 이벤트를 발생시켜달라는 요청에 불과하며 어디서 발생했는 지는 검증하지 않는다.
    • 아마도 "XX" 이름 이벤트가 없으면, 없다고 에러도 발생시키지 않을 것 이다.
    • Vuex를 이용하여 이러한 이벤트 문제에 대해서 에러를 반환하여 알려준다.
  • Vuew를 사용하면?!
    • MVC 패턴에서 발생하는 구조적 오류 해결
    • 컴포넌트 간 데이터 전달 명시적으로 전환
    • 여러 개의 컴포넌트에서 같은 데이터를 업데이트 할 때 동기화 문제 해결

Vuex 개념

  • Flux와 동일하게 단방향 통신이다.
  • State : 상태값, 컴포넌트 간 공유하는 데이터 data()
  • View : 데이터를 표시하는 화면 template
  • Action : 사용자의 입력에 따라 데이터를 변경하는 methods

 

  • Ex) 사용자가 View를 보고 특정 컴포넌트를 클릭하면 Action이 발생하여 State가 변경되고 이 변경된 내용은 다시 View에 적용된다.

Vuex 구조

  • 컴포넌트 -> 비동기 로직 -> 동기 로직 -> 상태
  • Vue Components -> Actions(Backend API 호출 - 비동기) -> Mutations(메소드 호출 - 동기) -> State(데이터) ...

Vuex 설치 및 등록

  • ES6와 함께 사용하면 더 많은 기능과 이점이 있다.
  • 모든 Vue 객체에서 접근 할 수 있는 Vuex (상태관리 객체)를 이용하기
    • Vuex 객체를 만든다. import 하는 것 만으로 만들어진다.
    • Vuex 객체를 Vue의 모듈로 등록한다.
      • 프로토타입을 변경하여 모든 Vue에서 Vuex에 액세스 할 수 있는 것으로 판단됨
  • Vue 프로젝트를 yarn으로 만들었다면, Vuex 모듈 설치 또한 yarn으로 해야 될 것으로 판단된다.
    • 동일한 이름의 모듈이라고 하더라도 버전에 따라 서로 다른 의존성을 가지고 있기 때문이 아닐까?
    • Npm으로 설치하니, 다수의 ERR이 보여서 불안하다.
    • Yarn으로 설치해도, 다수의 ERR이 보이는 건 마찬가지이다.

Vuex 기술 요소

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

state

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

// Vuex
state : {
  message : 'Hello Vue.js'
}
<!-- Vue -->
<p>{{ message }}</p>

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

getters

  • state 값을 접근하는 속성이자 computed()처럼 미리 연산된 값을 접근하는 속성
  • 추가로 helper 함수를 이용하면 더욱 더 간편하게 접근할 수도 있다.
// 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()으로 동작시킨다.
  • mutation 메소드 내에서는 Vuex의 state를 곧바로 접근 할 수 없게 구현되어 있다.
    • 그렇기 때문에 각 mutation 메소드의 첫번째 인수는 vuex의 state를 전달 받는다.
    • ( 이렇게 구현된 이유는 아래에 설명한다. )
// store.js
state : { num : 10 },
mutations : {
  printNumbers(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)를 전달할 수 있음
    • payload는 어딘가에 탑제하는 것 ( 화물, 사람 등등 )으로 적절한 비유이다. 데이터의 묶음을 전달 정도라 생각하자.
  • commit('호출하려는 mutations 이름', payload);
    • 여러 값을 보내야할 때는 인수 여러개가 아닌 객체로 만들어서 전달해야한다.
    • 구현 상 하나의 인수만 받게 되어있다. payload가 아닌 여러 인수로 보낸 경우, 두번째 인수부터 undefind가 나온다.
      • 이러한 부분은 에러로 잡아주지 않는다. Typescript가 필요한 시점이다.
      • ( 자바스크립트로만 API를 구현하였을때, 발생하게 될 문제가 보인다... 정말 API를 잘못 사용하게 될 확률이 높다. )
// 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를 변경했는지 추적하기 어렵다.
    • 디버깅이 어렵고 유지보수하기 어렵게 된다는 것을 의미한다.
    • ( 우왕~ 존잘알들~ 선경험자들 덕분에 개고생을 덜 합니다! 감사! 진짜 jQuery 할 시간에 곧 바로 vue.js 또는 react.js를 배우는 게 이기는 싸움이다. )
  • 특정 시점에 어떤 컴포넌트가 state를 접근하여 변경한 건지 확인하기 어렵기 때문! ( 위 내용과 동일한 말 )
  • 뷰의 구조를 거스르지 않고 명시적 상태 변화를 수행, 반응성, 디버깅, 테스팅 혜택 ( 반응성은 아직 체감이 안 된다. )

actions란?

  • vuex의 기술요소 중 하나인 actions는 비동기 처리 로직을 선언하는 메서드, 비동기 로직을 담당하는 mutations
    • API 서버 호출하는 부분 정도
  • actions에서 mutations로 액세스 하기 위하여 context를 인자로 전달한다.
    • 비동기 처리 로직을 간편하게 만들 수 있을 것으로 판단됨
  • action은 dispatch API로 호출합니다.
  • ( 백엔드 API 호출 로직과 vue 객체의 메소드 메소드 호출 로직이 분할 되어 유지보수가 용이할 것으로 판단된다.
// store.js
mutations : {
  setData(state, fetchedData) {
    state.product = fetchedData;
  }
},
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에 선언해야 할까?

  • mutations의 각 메소드에서 state를 전역으로 접근 할 수 없데 된 것 이유랑 동일하다.
    • action 없이 mutations의 각 메소드를 호출하면 추적이 어렵다. ( 어느 컴포넌트에서 시작 된 것인지 알 수 있을까? )
    • 비동기 처리는 actions에서 처리한 결과에 대해서 mutations에서 동기적으로 처리한다.

위 내용을 암기 및 이해하기 위해 두 번 보고 세번 보고 네번 보고 흐름에 익숙해져라.

 

블로그 이미지

_김은찬

두번 다시는 꺾이지 않으리

,