![저작자표시-비영리-변경금지 88x31.png](https://licensebuttons.net/l/by-nc-nd/3.0/88x31.png)
Vuex는 Vue로 작성된 어플리케이션의 상태를 통합적으로 관리할 수 있도록 도와주는 라이브러리입니다.
어플리케이션의 규모가 커지면 컴포넌트가 많아지고, 각 컴포넌트의 상태는 분산됩니다. 컴포넌트가 많아질 수록 각각의 상태에 대한 상호작용이 어려워지는데, Vuex는 분산된 상태를 하나의 저장소에 모아 복잡한 상호작용을 단순화 할 수 있습니다.
1. Flux 패턴
Flux는 기존의 MVC 패턴의 문제점을 해결하기 위해 페이스북에서 고안한 아키텍처입니다.
MVC 패턴의 컨트롤러(Controller)는 모델(Model)의 데이터를 조회하거나 업데이트하는 역할을 하며, 모델(Model)의 변화는 뷰(View)에 반영됩니다. 또한 사용자가 뷰(View)를 통해 데이터를 입력하면, 모델(Model)에 영향을 주면서 데이터를 관리합니다.
MVC 패턴의 데이터 흐름 ![](data:image/png;base64,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)
MVC 패턴을 사용함으로써 개발자들은 조금 더 확장이 유연하고 유지 보수하기에 용이한 어플리케이션을 작성할 수 있습니다.
그러나 MVC 패턴의 문제 중 하나는 하나의 컨트롤러가 여러 개의 모델이나 뷰를 컨트롤러를 제어할 수 있다는 점입니다. 페이스북과 같은 대규모 어플리케이션들이 등장하게 되면서 어플리케이션의 내부 구조가 복잡하게 되었습니다.
MVC 패턴의 복잡성
이를 해결하고자 페이스북 개발팀은 Flux 아키텍처를 개발했습니다. Flux 패턴의 경우 MVC 패턴과 달리 데이터 흐름이 양방향이 아닌 단방향으로 흐릅니다.
Flux 패턴의 데이터 흐름
Flux 패턴에서 데이터는 언제나 액션 -> 디스패처 -> 스토어 -> 뷰의 순서로 흐르기 때문에 뷰에서 사용자 액션에 의하여 데이터가 업데이트 된다면 액션부터 다시 시작하여 디스패처를 통해 스토어에 있는 데이터를 업데이트한 후 뷰에 반영합니다.
이러한 단방향 데이터의 흐름은 데이터의 상태를 예측하기 쉽게 만들어 디버깅을 용이하게 함으로써 유지보수를 용이하게 합니다.
1) 액션(Action)
스토어(Store)를 변경하기 위해서는 디스패처(Dispatcher)를 통한 업데이트가 이루어져야 하는데, 이때 디스패처를 실행시키는 인수 객체가 액션(Action)입니다.
액션은 타입(type)과 페이로드(payload)로 이루어진 단순한 객체입니다.
액션(Action)
{ type: 'INCREASE_NUM', payload: { num: 1 } } |
액션의 타입은 개발자가 직정 정의한 상수입니다. 이러한 액션은 액션 생성자(Action Creator)를 통해 생성됩니다.
2) 디스패처(Dispatcher)
디스패처(Dispatcher)는 Flux의 모든 데이터 흐름을 관리하는 역할을 합니다. 액션에 대한 콜백 함수를 제공하며, 액션이 발생하면 디스패처의 콜백 함수를 통해 액션의 메시지를 전달받습니다.
3) 스토어(Store)
스토어(Store)는 어플리케이션의 모든 상태와 로직을 담고 있으며, MVC 패턴의 모델(Model)과 같은 역할을 합니다.
스토어의 상태를 변경하기 위해서는 반드시 액션을 생성한 후 디스패처를 통해 스토어 상태 변경을 요청해야 합니다.
콜백 함수를 통해 스토어 상태가 변경되면 이벤트를 통해 뷰(View)에 새로운 상태를 전달하여 뷰가 스스로 업데이트 하도록 합니다.
4) 뷰(View)
Flux 패턴의 뷰(View)는 MVC 패턴의 뷰와는 다르게 단순히 화면을 렌더링하는 것 이외에도 컨트롤러(Controller) 역할을 하기도 합니다.
최상위 뷰는 스토어의 상태를 가져와 자식 뷰에 분배하는 역할을 하기 때문에 컨트롤러-뷰(Controller-View)라고도 부릅니다.
자식 뷰는 직접 스토어의 데이터를 받아오는 대신 부모 뷰로부터 Props를 통해 데이터를 전달받습니다.
2. Vuex
Vuex는 Flux 아키텍처에 영감을 받아 제작된 상태관리 라이브러리입니다. 많은 부분에서 Flux 아키텍처의 메커니즘을 차용하고 있습니다.
Vuex의 데이터 흐름 ![](data:image/png;base64,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)
Vue에서 Vuex를 사용하려면 Vue.use(Vuex)를 입력하여 Vuex의 사용을 선언해야합니다.
Vuex 사용 선언
import Vue from 'vue' import Vuex from 'vuex'
Vue.use(Vuex) |
하지만 CDN을 통해 Vuex를 import하여 모듈방식으로 개발하는 경우 Vuex를 로드하면 자동으로 Vuex를 사용하도록 설정되기 때문에 생략가능합니다. Vue 2버전의 경우 Vuex 3버전을 로드합니다.
Vuex의 사용을 선언하고 Vue 인스턴스의 옵션으로 store를 넣어주면 해당 컴포넌트에서 스토어를 사용할 수 있습니다.
index.html
main.js
import store from "./store.js";
new Vue({ store, }).$mount('#app') |
store.js
export default new Vuex.Store(); |
이제 스토어의 옵션을 알아보겠습니다.
1) 상태(State)
상태(State)는 어플리케이션에서 공통으로 관리할 상태, 즉 모델(Model)을 의미합니다. Vuex는 단일 상태 트리를 사용하며, 이 단일 객체는 원본 소스의 역할을 합니다. 이는 각 어플리케이션마다 하나의 저장소만 갖게 된다는 것을 의미합니다.
컴포넌트에서 스토어의 접근은 $store 프로퍼티를 통해 접근할 수 있으며, 컴포넌트에서 스토어의 상태에 접근하려면 Vue 인스턴스의 computed를 통해 접근합니다.
index.html
main.js
import store from "./store.js";
new Vue({ store, computed: { num() { return this.$store.state.num; } } }).$mount('#app') |
store.js
export default new Vuex.Store({ state: { num: 0 } }); |
출력 결과
this.$store.state를 통해 상태에 접근하면 여러 상태에 접근할 경우 반복적이고 장황해질 수 있는데, 이때 Vuex에서 제공하는 mapState 헬퍼 함수를 사용하면 간결하게 접근할 수 있습니다.
main.js
import store from "./store.js";
new Vue({ store, computed: Vuex.mapState(['num']) }).$mount('#app') |
헬퍼 함수 뿐만 아니라 다른 computed를 함께 사용하고 싶다면 객체 전개 연산자(Object Spread Operator)를 사용하면 됩니다.
main.js
import store from "./store.js";
new Vue({ store, computed: { ...Vuex.mapState(['num']) } }).$mount('#app') |
2) 게터(Getters)
게터(Getters)는 스토어 내에서 Vue의 computed와 같은 역할을 합니다. 컴포넌트에서 스토어 상태를 기반으로 상태를 계산하는 경우 다음과 같이 작성할 수 있습니다.
main.js
import store from "./store.js";
new Vue({ store, computed: { double: { return 2 * this.$store.state.num; } } }).$mount('#app') |
double 데이터는 스토어에 있는 num 데이터에 2를 곱한 값을 반환합니다. 간단한 식이기 때문에 문제없어 보이지만 만약 식이 복잡할 경우 해당 리턴값을 다른 컴포넌트에서 사용한다면 동일한 식을 중복해서 작성해야 합니다.
게터를 사용한다면 중복된 식을 각각의 컴포넌트에 작성할 필요없이 스토어로부터 캐시된 데이터값을 가져올 수 있게 됩니다.
index.html
main.js
import store from "./store.js";
new Vue({ store, computed: { double() { return this.$store.getters.double; } } }).$mount('#app') |
store.js
export default new Vuex.Store({ state: { num: 2 }, getters: { double(state, _getters){ return 2 * state.num } } }); |
출력 결과
getters에 선언된 함수는 1번째 매개변수로 스토어의 상태를, 2번째 매개변수로 getters 속성 자체를 전달받습니다.
상태와 마찬가지로 Vuex의 mapGetters 헬퍼 함수를 통해 간결한 접근을 할 수도 있습니다.
main.js
import store from "./store.js";
new Vue({ store, computed: Vuex.mapGetters(['double']) }).$mount('#app') |
역시 헬퍼 함수 뿐만 아니라 다른 computed를 함께 사용하고 싶다면 객체 전개 연산자(Object Spread Operator)를 사용하면 됩니다.
main.js
import store from "./store.js";
new Vue({ store, computed: { ...Vuex.mapGetters(['double']) } }).$mount('#app') |
3) 변이(Mutation)
변이(Mutation)는 스토어 상태를 변경할 수 있는 유일한 방법입니다. 변이 함수의 이름은 액션의 타입과 동일하며, 스토어 상태를 변경하는 로직을 가집니다.
index.html
main.js
import store from "./store.js";
new Vue({ store, computed: Vuex.mapState(['num']), methods: { increment() { this.$store.commit('INCREMENT', 10) } } }).$mount('#app') |
store.js
export default new Vuex.Store({ state: { num: 0 }, mutations: { INCREMENT (state, payload) { state.num += payload } } }); |
출력 결과
mutations에 선언된 함수는 1번째 매개변수로 스토어의 상태를, 2번째 매개변수로 payload를 전달받습니다.
컴포넌트에서 변이에 접근하려면 this.$store.mutations와 같은 직접적인 접근은 불가하며, 스토어의 commit 메소드를 실행시켜야 합니다. 1번째 매개변수로 변이 함수 이름(액션 타입)을, 2번째 매개변수로 payload를 전달합니다.
변이 역시 Vuex에서 mapMutations 헬퍼 함수를 제공하고 있으므로 다음과 같이 작성할 수 있습니다.
main.js
import store from "./store.js";
new Vue({ store, computed: Vuex.mapState(['num']), methods: { ...Vuex.mapMutations(['INCREMENT']), increment() { this.INCREMENT(10) } } }).$mount('#app') |
4) 액션(Actions)
변이 안에서 중요한 사실은 반드시 동기적(Synchronized)이어야 한다는 것입니다. Vue의 공식 디버그 툴인 Vue Devtools는 UI를 통해 변이를 추적하여 스토어의 상태를 확인할 수 있는데, 이때 변이의 추적은 commit 메소드의 호출을 기준으로 합니다.
만약 변이를 비동기(Asynchronized) 함수로 작성한다면 commit 시점과 콜백 시점이 다르기 때문에 어플리케이션의 상태 추적을 힘들게 만들 수 있습니다.
아래와 같이 INCREMENT 변이 함수에 setTimeout을 통해 비동기적으로 상태를 변경시켜 보겠습니다.
store.js
export default new Vuex.Store({ state: { num: 0 }, mutations: { INCREMENT (state, payload) { setTimeout(function() { state.num += payload }, 1000) } } }); |
출력 결과를 확인하면 Vue Devtools에서 스토어 상태를 제대로 반영하지 못하는 것을 확인할 수 있습니다.
출력 결과
이를 해결하기 위한 기능이 액션(Actions)입니다.
액션 함수를 비동기로 작성하여 콜백 함수에서 commit를 통해 변이 함수를 호출하여 스토어 상태를 변경할 수 있습니다.
main.js
import store from "./store.js";
new Vue({ store, computed: Vuex.mapState(['num']), methods: { increment() { this.$store.dispatch('increment', 10) } } }).$mount('#app') |
store.js
export default new Vuex.Store({ state: { num: 0 }, mutations: { INCREMENT (state, payload) { state.num += payload } }, actions: { increment (context, payload) { setTimeout(function() { context.commit('INCREMENT', payload) }, 1000) } } }); |
출력 결과
actions에 선언된 함수는 1번째 매개변수로 스토어 context 자체를, 2번째 매개변수로 payload를 전달받습니다.
컴포넌트에서 액션에 접근하려면 스토어의 dispatch 메소드를 실행시켜야 합니다. 1번째 매개변수로 액션 함수 이름을, 2번째 매개변수로 padyload를 전달합니다.
변이 역시 Vuex에서 mapActions 헬퍼 함수를 제공하고 있으므로 다음과 같이 작성할 수 있습니다.
index.html
main.js
import store from "./store.js";
new Vue({ store, computed: Vuex.mapState(['num']), methods: { ...Vuex.mapActions(['increment']), incrementHandler() { this.increment(10) } } }).$mount('#app') |
|