๋ค์ด๊ฐ๋ฉฐ
์ด ๊ธ์ Vue.js์ ์ปดํฌ๋ํธ์ ์ปดํฌ๋ํธ ํต์ ๋ฐฉ๋ฒ์ ์๊ณ ๊ณ์ ๋ถ๋ค์ด ์ฝ๊ธฐ ์ข์ต๋๋ค. Vue.js๋ฅผ ์ ๋ชจ๋ฅด์๊ฑฐ๋ ์ด์ ๋ง ์์ํ์๋ ๋ถ๋ค์ Vue ์ ๋ฌธ ๊ฐ์ด๋๋ฅผ ๋จผ์ ์ฝ์ด๋ณด์๊ณ ์ค์ธ์ :)
Vuex๋?
Vue.js์ ์ํ ๊ด๋ฆฌ๋ฅผ ์ํ ํจํด์ด์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค. ๋ค๋ฅธ ์ํ ๊ด๋ฆฌ ํจํด์ด๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋น๊ตํ์ ๋ ๋ทฐ์ ๋ฐ์์ฑ(Reactivity) ์ฒด๊ณ๋ฅผ ํจ์จ์ ์ผ๋ก ํ์ฉํ์ฌ ํ๋ฉด์ ์ ๋ฐ์ดํธ ํ๋ค๋ ์ฐจ์ด์ ์ด ์์ต๋๋ค.
์ํ ๊ด๋ฆฌ(State Management)๊ฐ ์ ํ์ํ๊ฐ?
์ปดํฌ๋ํธ ๊ธฐ๋ฐ ํ๋ ์์ํฌ์์๋ ์์ ๋จ์๋ก ์ชผ๊ฐ์ง ์ฌ๋ฌ ๊ฐ์ ์ปดํฌ๋ํธ๋ก ํ๋ฉด์ ๊ตฌ์ฑํฉ๋๋ค. ์๋ฅผ ๋ค๋ฉด, header, button, list ๋ฑ์ ํ๋ฉด ์์๊ฐ ๊ฐ๊ฐ ์ปดํฌ๋ํธ๋ก ๊ตฌ์ฑ๋์ด ํ ํ๋ฉด์์ ๋ง์ ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ด์ ๋ฐ๋ผ ์ปดํฌ๋ํธ ๊ฐ์ ํต์ ์ด๋ ๋ฐ์ดํฐ ์ ๋ฌ์ ์ข ๋ ์ ๊ธฐ์ ์ผ๋ก ๊ด๋ฆฌํ ํ์์ฑ์ด ์๊น๋๋ค.
์ํ ๊ด๋ฆฌ๋?
์ํ ๊ด๋ฆฌ๋ ์ฌ๋ฌ ์ปดํฌ๋ํธ ๊ฐ์ ๋ฐ์ดํฐ ์ ๋ฌ๊ณผ ์ด๋ฒคํธ ํต์ ์ ํ๊ณณ์์ ๊ด๋ฆฌํ๋ ํจํด์ ์๋ฏธํฉ๋๋ค. ๋ทฐ์ ์ฑ๊ฒฉ์ด ๋น์ทํ ํ๋ ์์ํฌ์ธ ๋ฆฌ์กํธ(React)์์๋ Redux, Mobx์ ๊ฐ์ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๊ณ ์๊ณ ๋ทฐ์์๋ Vuex๋ผ๋ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
์ํ ๊ด๋ฆฌ๋ก ํด๊ฒฐํ ์ ์๋ ๋ฌธ์ ์ ?
์ํ ๊ด๋ฆฌ๋ ์ค๋ํ ๊ท๋ชจ์ ์น ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ปดํฌ๋ํธ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ ํจ์จ์ ์ผ๋ก ์ ๋ฌํ ์ ์์ต๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ์ฑ์ ๊ท๋ชจ๊ฐ ์ปค์ง๋ฉด์ ์๊ธฐ๋ ๋ฌธ์ ์ ๋ค์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ๋ทฐ์ ์ปดํฌ๋ํธ ํต์ ๋ฐฉ์์ธ props, event emit ๋๋ฌธ์ ์ค๊ฐ์ ๊ฑฐ์ณํ ์ปดํฌ๋ํธ๊ฐ ๋ง์์ง๊ฑฐ๋
- ์ด๋ฅผ ํผํ๊ธฐ ์ํด Event Bus๋ฅผ ์ฌ์ฉํ์ฌ ์ปดํฌ๋ํธ ๊ฐ ๋ฐ์ดํฐ ํ๋ฆ์ ํ์ ํ๊ธฐ ์ด๋ ค์ด ๊ฒ
์ด๋ฌํ ๋ฌธ์ ์ ์ ํด๊ฒฐํ๊ธฐ ์ํด ๋ชจ๋ ๋ฐ์ดํฐ ํต์ ์ ํ ๊ณณ์์ ์ค์ ์ง์ค์์ผ๋ก ๊ด๋ฆฌํ๋ ๊ฒ์ด ์ํ ๊ด๋ฆฌ์ ๋๋ค.

์ํ ๊ด๋ฆฌ ํจํด
์ํ ๊ด๋ฆฌ ๊ตฌ์ฑ์์๋ ํฌ๊ฒ 3๊ฐ์ง๊ฐ ์์ต๋๋ค.
- state : ์ปดํฌ๋ํธ ๊ฐ์ ๊ณต์ ํ data
- view : ๋ฐ์ดํฐ๊ฐ ํํ๋ template
- actions : ์ฌ์ฉ์์ ์ ๋ ฅ์ ๋ฐ๋ผ ๋ฐ์ํ methods
new Vue({
// state
data() {
return {
counter: 0
};
},
// view
template: `
<div>{{ counter }}</div>
`,
// actions
methods: {
increment() {
this.counter++;
}
}
});
์ ๊ตฌ์ฑ์์๋ ์๋์ ๊ฐ์ ํ๋ฆ์ผ๋ก ๋์ํฉ๋๋ค.

Vuex ํํ ๋ฆฌ์ผ #1 - ๊ฐ๋จํ Vue App ๊ตฌ์ฑ
๋ทฐ์์ค๋ฅผ ์์๋ณด๊ธฐ ์ํด ๋ฒํผ์ผ๋ก ์ซ์๋ฅผ ๋๋ฆฌ๊ณ ์ค์ผ ์ ์๋ ์นด์ดํฐ ์ฑ์ ๋ง๋ค์ด๋ณด๊ฒ ์ต๋๋ค. Vue CLI๋ก ํ๋ก์ ํธ๋ฅผ ์์ฑํ ๋ค์ ์๋์ ๊ฐ์ด Parent, Child ์ปดํฌ๋ํธ๋ฅผ ์ ์ํฉ๋๋ค.

์ปดํฌ๋ํธ ํด๋๊ตฌ์กฐ๋ ์๋์ ๊ฐ์ต๋๋ค.
App.vue
: ์์ ์ปดํฌ๋ํธ ๋๋ ParentChild.vue
: ํ์ ์ปดํฌ๋ํธ ๋๋ Child
์ด ์ฑ์ ํน์ง์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ์ ์ฑ์
+
๋ฒํผ์ ํด๋ฆญํ๋ฉด ์นด์ดํฐ๊ฐ ์ฌ๋ผ๊ฐ๊ณ-
๋ฒํผ์ ํด๋ฆญํ๋ฉด ์นด์ดํฐ๊ฐ ๊ฐ์๋ฉ๋๋ค. - Parent ์ปดํฌ๋ํธ - Child ์ปดํฌ๋ํธ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ ๋ props ์์ฑ์ ์ฌ์ฉํ๋ค.
- ๋ฐ๋ผ์, ์์ ์ปดํฌ๋ํธ(Parent)์ ํ์ ์ปดํฌ๋ํธ(Child)๋ ๊ฐ์ ๋ฐ์ดํฐ(counter)๋ฅผ ๊ฐ์ต๋๋ค.
Vuex ํํ ๋ฆฌ์ผ #2 - Parent, Child ์ปดํฌ๋ํธ ์ฝ๋ ์ดํด๋ณด๊ธฐ
๋จผ์ , ์์ ์ปดํฌ๋ํธ์ธ App.vue(Parent)์ ํ ํ๋ฆฟ ์ฝ๋๋ฅผ ๋ณด๊ฒ ์ต๋๋ค.
<!-- App.vue(Parent) -->
<div id="app">
Parent counter : {{ counter }} <br>
<button @click="addCounter">+</button>
<button @click="subCounter">-</button>
<!-- Child ์ปดํฌ๋ํธ๋ฅผ ๋ฑ๋กํ๊ณ counter ๋ฐ์ดํฐ ์์ฑ์ props๋ก ์ ๋ฌํ๋ค. -->
<child v-bind:num="counter"></child>
</div>
์นด์ดํฐ๋ฅผ ํ๋ฉด์ ํ์ํ๊ณ ์นด์ดํฐ์ ๊ฐ์ ๋๋ ธ๋ค ์ค์๋ค ํ ์ ์๋ ๋ฒํผ 2๊ฐ๊ฐ ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ํ์ ์ปดํฌ๋ํธ์ธ child
์ปดํฌ๋ํธ๋ฅผ ๋ฑ๋กํ๊ณ counter
๋ฅผ props ์์ฑ์ผ๋ก ๋ด๋ ธ์ต๋๋ค.
๋ค์์ผ๋ก๋ App.vue
์ ์ธ์คํด์ค ์ต์
์์ฑ์ ๋ณด๊ฒ ์ต๋๋ค.
// App.vue(Parent)
import Child from "./Child.vue";
export default {
components: {
// Child ์ปดํฌ๋ํธ๋ฅผ ํ์ ์ปดํฌ๋ํธ๋ก ๋ฑ๋ก
child: Child
},
data() {
return {
counter: 0
};
},
methods: {
// ์ด๋ฒคํธ ์ถ๊ฐ
addCounter() {
this.counter++;
},
subCounter() {
this.counter--;
}
}
};
์ ์ฝ๋์์๋ ๋ฐ์ดํฐ ์์ฑ์ธ counter
๋ฅผ ์ ์ธํ๊ณ counter
๋ฅผ ๋๋ฆฌ๊ฑฐ๋ ์ค์ผ ์ ์๋ ๋ฉ์๋๋ฅผ 2๊ฐ ๋ฑ๋กํ์์ต๋๋ค.
๋ค์์ผ๋ก ํ์ ์ปดํฌ๋ํธ์ ์ฝ๋๋ฅผ ๋ณด๊ฒ ์ต๋๋ค.
<!-- Child.vue(Child) -->
<div>
<hr>
Child counter : {{ num }} <br>
<button>+</button>
<button>-</button>
</div>
// Child.vue(Child)
export default {
// ์์ ์ปดํฌ๋ํธ์์ ๋ด๋ ค์ค counter ์์ฑ์ num๋ก ๋ฐ์
props: ["num"]
};
ํ
ํ๋ฆฟ ์ฝ๋์ ๊ตฌ๋ถ์ (hr ํ๊ทธ)์ ์ ์ธํ๊ณ ๋ Parent ์ปดํฌ๋ํธ์ ์ ์ฌํ ์ฝ๋์
๋๋ค. ํ๋ฉด์ ํ์๋ ์นด์ดํฐ๋ Parent ์ปดํฌ๋ํธ์์ ์ ๋ฌ๋ฐ์ props
์์ฑ์
๋๋ค.
Vuex ํํ ๋ฆฌ์ผ #3 - Vue App ๋ถ์
์ ์ฑ์ +
๋ฒํผ์ ํด๋ฆญํ๋ฉด Parent์ Child ์ปดํฌ๋ํธ์ ์ซ์๊ฐ ๋์ผํ๊ฒ ์ฌ๋ผ๊ฐ๋๋ค.

์๋ํ๋ฉด ์์ ์ปดํฌ๋ํธ์ counter
๋ฐ์ดํฐ๋ฅผ props ์์ฑ์ผ๋ก ๋๊ฒจ ๋ฐ์๊ธฐ ๋๋ฌธ์
๋๋ค.
๋ฌ๋ฆฌ ๋งํด, ๊ฐ์ ๋ฐ์ดํฐ ์์ฑ์ 2๊ฐ์ ์ปดํฌ๋ํธ์์ ์ ๊ทผํ์ฌ ๊ฐ์ ๊ฐ์ ํํํ๊ณ ์๋ค๋ ์๋ฏธ์ ๋๋ค. ์ด ๊ตฌ์กฐ๋ ๋ทฐ์ props ์์ฑ์ ์ด์ฉํ ๊ธฐ๋ณธ์ ์ธ ์ปดํฌ๋ํธ ํต์ ๋ฐฉ๋ฒ์ ๋๋ค.
ํ๋ฉด์ ๋จ์๋ฅผ ์๊ฒ ์ชผ๊ฐ๋ฉด ์ชผ๊ฐค์๋ก ํ ์ปดํฌ๋ํธ์ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฅธ ์ปดํฌ๋ํธ์ ํ๋ฉด์์ ํ์ํ ์ผ์ด ๋ง์์ง๋๋ค. ๋ง์ฝ ์ปดํฌ๋ํธ์ ๊ฐฏ์๊ฐ ๋ฌดํ์ ๋ง์์ง๋ค๋ฉด ์ด๋ป๊ฒ ๋ ๊น์? ์ต์์ ์ปดํฌ๋ํธ์์ ๋งจ ์๋์ ์ปดํฌ๋ํธ์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๊ธฐ ์ํด ์ค๊ฐ ๊ณ์ธต์ ์ปดํฌ๋ํธ์ ๋ชจ๋ props, event emit์ ์ ์ธํด์ค์ผ ํ ๊ฒ๋๋ค.
์ด์ ์ด ๋นํจ์จ์ ์ธ ์ปดํฌ๋ํธ ๊ฐ ๋ฐ์ดํฐ ์ ๋ฌ ๋ฐฉ์์ Vuex๋ก ํด๊ฒฐํด๋ด ์๋ค :)
Vuex ํํ ๋ฆฌ์ผ #4 - Vuex ์ค์น ๋ฐ ๋ฑ๋ก
๋จผ์ ์๋ ๋ช ๋ น์ด๋ก ํ๋ก์ ํธ์ Vuex๋ฅผ ์ค์นํฉ๋๋ค.
npm install vuex
๊ทธ๋ฆฌ๊ณ ๋ทฐ์์ค๋ฅผ ๋ฑ๋กํ ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ์ ํ๋ ์๋ก ์์ฑํฉ๋๋ค. ์ด๋ฆ์ ๊ด๋ก์ ๋ฐ๋ผ store.js
๋ก ์ง์ ํ๊ฒ ์ต๋๋ค.
// 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)
});
Vuex ํํ ๋ฆฌ์ผ #5 - state ๋ฑ๋ก
state๋ฅผ ๋ทฐ์์ค์ ์๋์ ๊ฐ์ด ์ถ๊ฐํฉ๋๋ค.
// 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 ์์ฑ counter
์ ๋์ผํ ์ญํ ์ ํฉ๋๋ค.
์ด๋ฏธ ์ ์ํ ๊ด๋ฆฌ ํจํด ์ฑํฐ์์ ์ค๋ช
ํ๋ฏ์ด โstate๋ ์ปดํฌ๋ํธ ๊ฐ์ ๊ณต์ ํ data ์์ฑ์ ์๋ฏธํฉ๋๋ค.โ
Vuex ํํ ๋ฆฌ์ผ #6 - state ์ ๊ทผ
๋ฐฉ๊ธ state์ ๋ฑ๋กํ counter
์์ฑ์ ์ปดํฌ๋ํธ์ ํ
ํ๋ฆฟ ์ฝ๋์์ $store.state.counter
๋ก ์ ๊ทผํ ์ ์์ต๋๋ค. ์์์ ์ดํด๋ณธ Parent ์ปดํฌ๋ํธ์ ์ ์ฉํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
<!-- App.vue(Parent) -->
<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>
// App.vue(Parent)
import Child from "./Child.vue";
export default {
components: {
child: Child
},
// ๊ธฐ์กด ์ฝ๋
// data () {
// return {
// counter: 0
// }
// },
methods: {
addCounter() {
this.$store.state.counter++;
},
subCounter() {
this.$store.state.counter--;
}
}
};
์ ์ฝ๋๋ ๊ธฐ์กด ์ฝ๋์ ๋ค์ 2๊ฐ์ง๊ฐ ๋ค๋ฆ ๋๋ค.
- data ์์ฑ์ผ๋ก ์ ์ธํ
counter
๊ฐ ์ ๊ฑฐ - Child ์ปดํฌ๋ํธ๋ก
counter
๋ฅผ ์ ๋ฌํ์ง ์์
๊ฒฐ๊ตญ Parent ์ปดํฌ๋ํธ์์ ๊ด๋ฆฌํ๋ counter
๋ฐ์ดํฐ๋ฅผ ๋ทฐ์์ค์ state์ ๋๊ฒจ์ฃผ์์ต๋๋ค. Child ์ปดํฌ๋ํธ์์ ์ ๊ทผํ๋ Parent ์ปดํฌ๋ํธ์ data ์์ฑ์ด ๋ทฐ์์ค๋ก ๊ฐ๊ธฐ ๋๋ฌธ์ ์ด์ Child์์๋ ๋ทฐ์์ค์ state๋ฅผ ๋ฐ๋ผ๋ณด๋ฉด ๋ฉ๋๋ค. ์ด์ Parent์ Child ๋ชจ๋ state๋ฅผ ์ ๊ทผํ ์ ์๊ฒ ๋์์ฃ . ๋ง์ฐฌ๊ฐ์ง๋ก ์ด๋ค ์ปดํฌ๋ํธ๋ ์ด์ ๋ทฐ์์ค๋ก counter
๋ฅผ ์ ๊ทผํ ์ ์์ต๋๋ค.

Parent ์ปดํฌ๋ํธ์ +
๋ฒํผ์ ๋๋ ์ ๋ ๋์ผํ๊ฒ ๋์ํ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.

ํ๋ฉด์์ผ๋ก๋ ์ด์ ๊ณผ ์ฐจ์ด๊ฐ ์์ง๋ง ๋ด๋ถ์ ์ผ๋ก๋ ๋ทฐ์์ค๋ฅผ ์ฌ์ฉํ๊ณ ์๋ค๋ ์ฐจ์ด๊ฐ ์์ต๋๋ค. ๋ทฐ์์ค๋ก ๋ฐ์ดํฐ ๊ด๋ฆฌ๋ฅผ ํ๊ธฐ ๋๋ฌธ์ Parent์ Child ๋ฟ๋ง ์๋๋ผ ๋ ๋ง์ ์ปดํฌ๋ํธ๋ค์ด counter
๊ฐ์ ์ ๊ทผํ ์ ์๊ฒ ๋์ฃ .
๋์ผํ๊ฒ Child ์ปดํฌ๋ํธ์๋ ๋ทฐ์์ค๋ฅผ ์ ์ฉํด๋ณด๊ฒ ์ต๋๋ค.
<div>
<hr />
Child counter : {{ $store.state.counter }} <br />
<button>+</button>
<button>-</button>
</div>
export default {
// ๊ธฐ์กด ์ฝ๋
// props: ['passedCounter']
};
Parent ์ปดํฌ๋ํธ์์ props ์์ฑ์ผ๋ก counter
๋ฅผ ์ ๋ฌ๋ฐ๋ ๋ฐฉ์์์ ๋ทฐ์์ค์ state์ธ counter
๋ฅผ ๋ฐ๋ก ์ ๊ทผํ๋ ๋ฐฉ์์ผ๋ก ๋ฐ๋์์ต๋๋ค.
๋ง๋ฌด๋ฆฌ
์ด์ฒ๋ผ ๋ทฐ์์ค๋ฅผ ์ด์ฉํ๋ฉด ์ฌ๋ฌ ์ปดํฌ๋ํธ ๊ฐ์ ๊ณต์ ํ ๋ฐ์ดํฐ๋ฅผ ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํ ์ ์์ต๋๋ค. ์ด์ธ์๋ state ๊ฐ์ ์ฝ๊ฒ ์ ๊ทผํ ์ ์๋ getters, state ๊ฐ์ ๋ณ๊ฒฝํ๋ mutations, ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ํ actions, ํด๋ ๊ตฌ์กฐํ ๋ฑ์ ์์์ผ ๋ทฐ์์ค๋ก ์น ์๋น์ค๋ฅผ ๊ฐ๋ฐํ ์ ์์ต๋๋ค.
๋ค์ ์๋ฆฌ์ฆ๊ฐ ๊ถ๊ธํ์๋ค๋ฉด ์๋ ๋งํฌ๋ฅผ ํ์ฉํด๋ณด์ธ์ :)
Vuex ์์ํ๊ธฐ 2ํ ๋ฐ๋ก๊ฐ๊ธฐ
Vuex ์์ํ๊ธฐ 3ํ ๋ฐ๋ก๊ฐ๊ธฐ
๊ธ๋ณด๋ค ๋ ์ฝ๊ฒ ๋ฐฐ์ฐ๋ ์จ๋ผ์ธ ๊ฐ์
์ข ๋ ์น์ ํ๊ณ ์์ธํ ์ค๋ช ์ ์ํ์ ๋ค๋ฉด ์๋ ๊ฐ์ข๋ฅผ ์ด์ฉํด๋ณด์๋ ๊ฒ๋ ์ข์ ๊ฒ ๊ฐ์์ ๐








