Vuex ์‹œ์ž‘ํ•˜๊ธฐ 1 - Vuex์™€ State

๋“ค์–ด๊ฐ€๋ฉฐ

์ด ๊ธ€์€ Vue.js์˜ ์ปดํฌ๋„ŒํŠธ์™€ ์ปดํฌ๋„ŒํŠธ ํ†ต์‹  ๋ฐฉ๋ฒ•์„ ์•Œ๊ณ  ๊ณ„์‹  ๋ถ„๋“ค์ด ์ฝ๊ธฐ ์ข‹์Šต๋‹ˆ๋‹ค. Vue.js๋ฅผ ์ž˜ ๋ชจ๋ฅด์‹œ๊ฑฐ๋‚˜ ์ด์ œ ๋ง‰ ์‹œ์ž‘ํ•˜์‹œ๋Š” ๋ถ„๋“ค์€ Vue ์ž…๋ฌธ ๊ฐ€์ด๋“œ๋ฅผ ๋จผ์ € ์ฝ์–ด๋ณด์‹œ๊ณ  ์˜ค์„ธ์š” :)

Vuex๋ž€?

Vue.js์˜ ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ ํŒจํ„ด์ด์ž ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์ƒํƒœ ๊ด€๋ฆฌ ํŒจํ„ด์ด๋‚˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ๋น„๊ตํ–ˆ์„ ๋•Œ ๋ทฐ์˜ ๋ฐ˜์‘์„ฑ(Reactivity) ์ฒด๊ณ„๋ฅผ ํšจ์œจ์ ์œผ๋กœ ํ™œ์šฉํ•˜์—ฌ ํ™”๋ฉด์„ ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค๋Š” ์ฐจ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ƒํƒœ ๊ด€๋ฆฌ(State Management)๊ฐ€ ์™œ ํ•„์š”ํ•œ๊ฐ€?

์ปดํฌ๋„ŒํŠธ ๊ธฐ๋ฐ˜ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ๋Š” ์ž‘์€ ๋‹จ์œ„๋กœ ์ชผ๊ฐœ์ง„ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ปดํฌ๋„ŒํŠธ๋กœ ํ™”๋ฉด์„ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด, header, button, list ๋“ฑ์˜ ํ™”๋ฉด ์š”์†Œ๊ฐ€ ๊ฐ๊ฐ ์ปดํฌ๋„ŒํŠธ๋กœ ๊ตฌ์„ฑ๋˜์–ด ํ•œ ํ™”๋ฉด์—์„œ ๋งŽ์€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด์— ๋”ฐ๋ผ ์ปดํฌ๋„ŒํŠธ ๊ฐ„์˜ ํ†ต์‹ ์ด๋‚˜ ๋ฐ์ดํ„ฐ ์ „๋‹ฌ์„ ์ข€ ๋” ์œ ๊ธฐ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ํ•„์š”์„ฑ์ด ์ƒ๊น๋‹ˆ๋‹ค.

์ƒํƒœ ๊ด€๋ฆฌ๋ž€?

์ƒํƒœ ๊ด€๋ฆฌ๋ž€ ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ ๊ฐ„์˜ ๋ฐ์ดํ„ฐ ์ „๋‹ฌ๊ณผ ์ด๋ฒคํŠธ ํ†ต์‹ ์„ ํ•œ๊ณณ์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ํŒจํ„ด์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋ทฐ์™€ ์„ฑ๊ฒฉ์ด ๋น„์Šทํ•œ ํ”„๋ ˆ์ž„์›Œํฌ์ธ ๋ฆฌ์•กํŠธ(React)์—์„œ๋Š” Redux, Mobx์™€ ๊ฐ™์€ ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๊ณ  ๋ทฐ์—์„œ๋Š” Vuex๋ผ๋Š” ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ƒํƒœ ๊ด€๋ฆฌ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ์ ?

์ƒํƒœ ๊ด€๋ฆฌ๋Š” ์ค‘๋Œ€ํ˜• ๊ทœ๋ชจ์˜ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์ปดํฌ๋„ŒํŠธ ๊ฐ„์— ๋ฐ์ดํ„ฐ๋ฅผ ๋” ํšจ์œจ์ ์œผ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ์•ฑ์˜ ๊ทœ๋ชจ๊ฐ€ ์ปค์ง€๋ฉด์„œ ์ƒ๊ธฐ๋Š” ๋ฌธ์ œ์ ๋“ค์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  1. ๋ทฐ์˜ ์ปดํฌ๋„ŒํŠธ ํ†ต์‹  ๋ฐฉ์‹์ธ props, event emit ๋•Œ๋ฌธ์— ์ค‘๊ฐ„์— ๊ฑฐ์ณํ•  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งŽ์•„์ง€๊ฑฐ๋‚˜
  2. ์ด๋ฅผ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด Event Bus๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ปดํฌ๋„ŒํŠธ ๊ฐ„ ๋ฐ์ดํ„ฐ ํ๋ฆ„์„ ํŒŒ์•…ํ•˜๊ธฐ ์–ด๋ ค์šด ๊ฒƒ

์ด๋Ÿฌํ•œ ๋ฌธ์ œ์ ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋ชจ๋“  ๋ฐ์ดํ„ฐ ํ†ต์‹ ์„ ํ•œ ๊ณณ์—์„œ ์ค‘์•™ ์ง‘์ค‘์‹์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์ƒํƒœ ๊ด€๋ฆฌ์ž…๋‹ˆ๋‹ค.

Vuex ์ „์ฒด ํ๋ฆ„๋„

์ƒํƒœ ๊ด€๋ฆฌ ํŒจํ„ด

์ƒํƒœ ๊ด€๋ฆฌ ๊ตฌ์„ฑ์š”์†Œ๋Š” ํฌ๊ฒŒ 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 ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

Parent ์ปดํฌ๋„ŒํŠธ์™€ Child ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ‘œ์‹œ๋œ ํ™”๋ฉด

์ปดํฌ๋„ŒํŠธ ํด๋”๊ตฌ์กฐ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

folder-structure

  • App.vue : ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ ๋˜๋Š” Parent
  • Child.vue : ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ ๋˜๋Š” Child

์ด ์•ฑ์˜ ํŠน์ง•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

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 ์†์„ฑ์œผ๋กœ ๋„˜๊ฒจ ๋ฐ›์•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

counter-reference

๋‹ฌ๋ฆฌ ๋งํ•ด, ๊ฐ™์€ ๋ฐ์ดํ„ฐ ์†์„ฑ์„ 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๊ฐ€์ง€๊ฐ€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

  1. data ์†์„ฑ์œผ๋กœ ์„ ์–ธํ•œ counter ๊ฐ’ ์ œ๊ฑฐ
  2. Child ์ปดํฌ๋„ŒํŠธ๋กœ counter ๋ฅผ ์ „๋‹ฌํ•˜์ง€ ์•Š์Œ

๊ฒฐ๊ตญ Parent ์ปดํฌ๋„ŒํŠธ์—์„œ ๊ด€๋ฆฌํ•˜๋˜ counter ๋ฐ์ดํ„ฐ๋ฅผ ๋ทฐ์—‘์Šค์˜ state์— ๋„˜๊ฒจ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. Child ์ปดํฌ๋„ŒํŠธ์—์„œ ์ ‘๊ทผํ•˜๋˜ Parent ์ปดํฌ๋„ŒํŠธ์˜ data ์†์„ฑ์ด ๋ทฐ์—‘์Šค๋กœ ๊ฐ”๊ธฐ ๋•Œ๋ฌธ์— ์ด์ œ Child์—์„œ๋Š” ๋ทฐ์—‘์Šค์˜ state๋ฅผ ๋ฐ”๋ผ๋ณด๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ด์ œ Parent์™€ Child ๋ชจ๋‘ state๋ฅผ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์ฃ . ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์–ด๋–ค ์ปดํฌ๋„ŒํŠธ๋“  ์ด์ œ ๋ทฐ์—‘์Šค๋กœ counter๋ฅผ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ทฐ์—‘์Šค์˜ counter๋ฅผ ์ ‘๊ทผํ•˜๋Š” Parent, Child ์ปดํฌ๋„ŒํŠธ์˜ ๋ชจ์Šต

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ํƒ„ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๊ธ€๋ณด๋‹ค ๋” ์‰ฝ๊ฒŒ ๋ฐฐ์šฐ๋Š” ์˜จ๋ผ์ธ ๊ฐ•์˜

์ข€ ๋” ์นœ์ ˆํ•˜๊ณ  ์ƒ์„ธํ•œ ์„ค๋ช…์„ ์›ํ•˜์‹ ๋‹ค๋ฉด ์•„๋ž˜ ๊ฐ•์ขŒ๋ฅผ ์ด์šฉํ•ด๋ณด์‹œ๋Š” ๊ฒƒ๋„ ์ข‹์„ ๊ฒƒ ๊ฐ™์•„์š” ๐Ÿ˜„

์ธํ”„๋Ÿฐ ์˜จ๋ผ์ธ ๊ฐ•์˜ : Vue.js ์‹œ์ž‘ํ•˜๊ธฐ / Vue.js ์ค‘๊ธ‰ / Vue.js ์™„๋ฒฝ ๊ฐ€์ด๋“œ
์ธํ”„๋Ÿฐ ์˜จ๋ผ์ธ ๊ฐ•์˜ : Vue.js ๋์žฅ๋‚ด๊ธฐ / ํ”„๋ŸฐํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ ์›นํŒฉ / PWA ์‹œ์ž‘ํ•˜๊ธฐ
์ธํ”„๋Ÿฐ ์˜จ๋ผ์ธ ๊ฐ•์˜ : ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์ž…๋ฌธ / ์‹ค์ „ ํ”„๋กœ์ ํŠธ๋กœ ๋ฐฐ์šฐ๋Š” ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ / Vue.js + TypeScript ์™„๋ฒฝ ๊ฐ€์ด๋“œ