Vuex 란?
What is Vuex?
Vuex 시작하기
state는 상태(state)의 집합니다.
Vuex는 단일 상태 트리(single state tree)를 사용하는데, 이는 하나의 어플리케이션은 하나의 store만 가진다는 뜻이다.
즉, 한 컴포넌트에서 동작해서 발생한 결과는 다른 모든 컴포넌트에도 동일하게 적용이 된다.
// store.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export const store = new Vuex.Store({
// counter라는 state(data) 속성을 추가
state: {
counter: 0
}
})
state에 정의된 counter 속성은 Parent 컴포넌트에서 사용하던 data 속성 counter와 동일한 역할을 한다.
즉, state는 컴포넌트간에 공유 할 data 속성을 의미한다.
state
에 등록한 counter
속성은 컴포넌트의 템플릿 코드에서 $store.state.counter
로 접근이 가능하다. 앞에서 살펴본 Parent 컴포넌트에 적용하면 다음과 같다.
// A.vue(Parent)
<template id="app">
<div>
This is B View
{{ count }}
</div>
<button @click="addCounter">+</button>
<button @click="subCounter">-</button>
// 기존 코드
// <child v-bind:num="counter"></child>
<child></child>
</template>
<script>
import Child from "./Child.vue";
export default {
components: {
child: Child
},
// 기존 코드
// data () {
// return {
// counter: 0
// }
// },
computed: {
count () {
return this.$store.state.count
}
}
methods: {
addCounter() {
this.$store.state.counter++;
},
subCounter() {
this.$store.state.counter--;
}
}
};
</script>
A.vue 코드는 기존코드와 다음 2가지가 다르다.
v-bind:num=”counter”
)Parent 컴포넌트에서 관리하던 counter 데이터를 vuex의 state에 넘겨주었고, Child 컴포넌트에서 접근하던 Parent 컴포넌트의 data 속성이 vuex로 갔기 때문에 Child에서는 vuex의 state를 바라보면 된다.
이렇게 Parente와 Child 모두 state를 접근할 수 있게 되었다. 마찬가지로 어떤 component든 vuex로 counter를 접근할 수 있다!
// B.vue(Parent)
<template>
<div>
This is B View
{{ count }}
</div>
</template>
<script>
export default {
computed: {
count () {
return this.$store.state.count
}
}
}
</script>
위 A.vue 와 B.vue 에는 동일한 state 의 count 를 불러왔다. A.vue에서 증가되는 addCounter 함수로 count 값을 증가시켰는데 B.vue의 count도 동일하게 증가되는 것을 확인할 수 있다. 이는 단일 상태 트리이기 때문에 발생하는 결과이다.
말 그대로 state 내의 상태가 유일 하다는 의미이다.
store의 count는 어플리케이션에서 단 하나만 존재하기 때문에 다른 컴포넌트에서 count의 상태가 변경되었다면, 현재 컴포넌트에도 그 변화된 상태를 출력해야만 한다. 그러기 위해서는 Vue의 computed 속성을 통해 store의 state를 출력해야 한다.
this.$store.state가 반복 선언되는 불필요함을 해결하기 위해 Vuex는 mapState라는 Helper 함수를 제공하고 있다.
import { mapState } from 'vuex'
export default {
// ...
computed: mapState({
// #1 화살표 함수로 가져오기
count: state => state.count,
// #2 문자열로 가져오기 (`state => state.count`와 같다.)
countAlias: 'count',
// #3 `this`를 사용하여 로컬 상태에 액세스하려면 일반적인 함수를 사용해야한다
countPlusLocalState (state) {
return state.count + this.localCount
}
// #4 this.count를 store.state.count에 매핑한다.
'count'
})
}
기존 현재 컴포넌트의 computed 와 함께 사용하려면 객체 전개 연산자를 사용하면 된다.
computed: {
...mapState({
// ...
})
localComputed () { /* ... */ }, // 기존의 computed
}