본문 바로가기
Dev/Vue.js

[Vue.js] Vuex - 주요 기술 요소

by dev_jsk 2020. 9. 11.
728x90
반응형

Vuex 설치하기

  • Vuex는 싱글 파일 컴포넌트 체계에서 NPM 방식으로 라이브러리를 설치하는게 좋다.
  • ES6와 함께 사용해야 더 많은 기능과 이점을 제공받을 수 있다.
// Terminal

npm install vuex --save

Vuex 등록하기

1. src/store/store.js 생성

// store.js

import Vue from "vue";
import Vuex from "vuex";

// Vue 플러그인 사용
// 전역 기능을 사용하기 위해
Vue.use(Vuex);

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

2. main.jsstore.js파일 import

// main.js

import Vue from 'vue'
import App from './App.vue'
import { store } from './store/store'

Vue.config.productionTip = false

new Vue({
  store,
  render: h => h(App),
}).$mount('#app')

Vuex 기술 요소

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()처럼 미리 연산된 값을 접근하는 속성
// 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의 값을 변경할 수 있는 유일한 방법이자 메서드
  • mutationcommit()으로 동작시킨다.
// store.js
state: {num: 10},
mutations: {
  // 첫번째 인자는 무조건 state
  printNumbers(state) {
    return state.num
  },
  sumNumbers(state, anotherNum) {
    return state.num + anotherNum;
  }
}

// App.vue
// commit(type, payload, options)
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 },
mutaions: {
  doubleNumber(state) {
    state.num * 2;
  }
},
actions: {
  delayDoubleNumber(context) { // context로 store의 mutations와 state 접근 가능
    // this.$store.commit('doubleNumber');
    context.commit('doubleNumber');
  }
}

// App.vue
this.$store.dispatch('delayDoubleNumber');  // actions 실행은 dispatch 함수 사용

actions 비동기 코드 예제 1

  • 2초정도 지난 후 카운트 증가하는 기능
// store.js
mutations: {
  addCounter(state) {
    state.counter++;
  }
},
actions: {
  delayedAddCounter(context) {
    setTimeout(() => context.commit('addCounter'), 2000);
  }
}

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

actions 비동기 코드 예제 2

  • 특정 url에서 상품 정보를 받아 저장하는 기능
// 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에 선언해야 하는가

  • 언제 어느 컴포넌트에서 해당 state를 호출하고, 변경했는지 확인하기가 어려움
  • 그렇기 때문에 state값의 변화를 추적하기 어렵기 때문에 mutations속성에는 동기 처리 로직만 넣어야 한다.

 

728x90
반응형

'Dev > Vue.js' 카테고리의 다른 글

[Vue.js] Vuex - 프로젝트 구조화 및 모듈화  (0) 2020.09.14
[Vue.js] Vuex - 헬퍼 함수  (0) 2020.09.14
[Vue.js] Vuex  (0) 2020.09.11
[Vue.js] ES6  (0) 2020.09.11
[Vue.js] Todo App 사용자 경험 개선하기  (0) 2020.09.10

댓글