Vue.js의 상태 관리를 위한 패턴이자 라이브러리입니다. 다른 상태 관리 패턴이나 라이브러리와 비교했을 때 뷰의 반응성(Reactivity) 체계를 효율적으로 활용하여 화면을 업데이트 한다는 차이점이 있습니다.
원래 기존 vue에서는 컴포넌트끼리 통신할때 props, emit 등을 지원합니다.
그러나 만약 hello
라는 변수를 100개의 컴포넌트에서 사용하면 어떨까요 ?
그때마다 props , emit 을 사용해서 통신을 해야하는데 아주아주 귀찮은 일이 아닐 수가 없습니다.
그래서 등장한게 바로 Vuex 입니다.
어짜피 자주 사용할 정보들은 Store
에 담아두고 중앙집중적으로 관리하자 ! 라는게 vuex 의 탄생배경입니다.
위에서 초록점선 부분이 Vuex 가 담당하는 부분입니다.
여기서 바로 State
라는 곳에 컴포넌트 간에 공유될 모든 data를 담아둡니다.
먼저 Vuex 없이 props
와 emit
을 이용한 전달을 알아봅시다 !
👇 Parent.vue
<template>
<div>
<p>Parent Counter : {{parentnum}}</p>
<child v-bind:childnum="parentnum"/>
<button @click='addnum'>+</button>
<button @click='subnum'>-</button>
</div>
</template>
<script>
import Child from './Child.vue';
export default {
components:{
Child,
},
data(){
return{
parentnum:0,
}
},
methods:{
addnum(){
return this.parentnum++;
},
subnum(){
return this.parentnum--;
}
}
}
</script>
부모 컴포넌트인 App.vue(Parent) 에서는 자식 컴포넌트인 Child 에게 v-bind
라는 directive 를 이용해서 자신이 가지고 있는 parentnum
이라는 변수를 넘겨주고 있습니다.
👇 Child.vue
<template>
<div>
<p> Child counter : {{ childnum }} </p>
</div>
</template>
<script>
export default {
props:["childnum"]
}
</script>
자식 컴포넌트인 App.vue(child) 에서는 props
속성을 이용해서 부모 컴포넌트로부터 데이터를 전달받습니다.
결과적으로 Parent 와 Child는 parentnum
과 childnum
. 즉 같은 데이터를 공유하게 되었습니다.
그런데 만약 Child1 , Child2, Child3 ... 처럼 무수히 많은 자식 컴포넌트가 있다면 이렇게 데이터를 공유하는건 너무나 귀찮습니다.
그럼 이제 Vuex 의 store 을 이용해서 데이터를 관리하고 서로 공유해보겠습니다.
👇 store.js ! 관례에 따라 정한 이름입니다.
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export const store = new Vuex.Store({
// ...
});
이제 main.js 파일에서 store.js를 불러오고 등록해야 합니다.
👇 main.js
import Vue from "vue";
import App from "./App.vue";
// store.js를 불러오는 코드
import { store } from "./store";
new Vue({
el: "#app",
// 뷰 인스턴스의 store 속성에 연결
store: store,
render: h => h(App)
});
👇 store.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export const store = new Vuex.Store({
//!!!!!!!!! 추가된 부분 !!!!!!!!!!!!!!
// counter라는 state 속성을 추가
state: {
counter: 0
}
//!!!!!!!!! 추가된 부분 !!!!!!!!!!!!!!
});
state에 정의된 counter
속성은 Parent 컴포넌트에서 사용하던 data 속성 parentnum
와 동일한 역할을 합니다. 이미 앞 상태 관리 패턴 챕터에서 설명했듯이 “state는 컴포넌트 간에 공유할 data를 의미합니다.”
방금 state에 등록한 counter
속성은 컴포넌트의 템플릿 코드에서 $store.state.counter
로 접근할 수 있습니다.
바로 이런식으로 말이죠.
👇 Parent.vue
<div id="app">
Parent counter : {{ $store.state.counter }} <br />
<button @click="addCounter">+</button>
<button @click="subCounter">-</button>
<!-- 기존 코드 -->
<!-- <child v-bind:num="counter"></child> -->
<child></child>
</div>
이제 굳이 Parent 에서 v-bind
로 값을 전달해주지 않아도 Child 는 Store
에서 데이터에 접근이 가능해졌습니다 !