Frontend-Vuejs

Vuex helpers - parent,child와 state

jiwoolee 2021. 8. 2. 18:33

Vuex helpers를 한번 더 이용해보자

이 예제는 캡틴 판교의 게시글에 올라와 있다

 

 

 

 

 

 

먼저 프로젝트를 만들어주고 해당 프로젝트로 이동

cd vuex_example

 

 

 

 

 

 

 

 

일단 parent component랑 child component를 만들어야지

/src/components에 각각 vue 파일을 만들어주자

 

//Parents.vue

<template>
<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>
</template>


<script>
import Child from "./Child.vue";

export default {
  components: {
    child: Child
  },
  data() {
    return {
      counter: 0
    };
  },
  methods: {
    addCounter() {
      this.counter++;
    },
    subCounter() {
      this.counter--;
    }
  }
};
</script>

 

//Child.vue

<template>
    <div>
  <hr>
  Child counter : {{ num }} <br>
  <button>+</button>
  <button>-</button>
</div>
</template>



<script> 
export default {
  props: ["num"]
};
</script>

 

 

 

 

당연히  Home.vue도 수정해줘야지

<template>
  <div id="app">
    <Parents></Parents>

  </div>
</template>

<script>
// @ is an alias to /src
import Parents from '../components/Parents.vue'


export default {
  name: 'Home',
  components: {
    Parents,
  }
}
</script>

 

 

 

 

 

 

 

근데 이렇게 되면,

Parents.vue = 상위 component의 counter 데이터를 prop속성으로 받았기 때문에

=> 같은 데이터 속성을 2개의 component에서 접근해 같은 값을 표현하는 거라

=> 버튼 클릭 시 parent, child component의 숫자가 동일하게 올라간다

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

세상 비효율적인 컴포넌트 간 데이터 전달을 Vuex로 해결해보자

npm install vuex

바로 vuex를 등록할 js파일을 하나 생성해주자

=> src/store/index.js 로 이미 존재하면 store.js로 바꿔주기만 하자

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export const store = new Vuex.Store({
  state: {
    counter: 0
  },
  mutations: {
  },
  actions: {
  },
  modules: {
  }
})

 

 

 

 

 

 

 

 

store.js를 쓰기 위해 main.js에 등록해줘야 한다

=> 이거도 되어있네...

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import {store} from './store/store'

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

 

 

 

 

 

 

 

 

오케이

이제 state부터 등록해주자

아까 써줬던 src/store/store.js로 가서 state를 추가하면 끝

state: {
counter: 0
}

 

여기서의 counter는 Parent component에서 사용하던 data 속성 counter랑 같다

 

 

 

 

 

 

 

 

state를 등록해줬으니 접근해보자

$store.state.counter로 접근할 수 있다

 

 

// Parents.vue

<template>
<div id="app">
  Parent counter : {{ $store.state.counter }} <br>
  <button @click="addCounter">+</button>
  <button @click="subCounter">-</button>
  <Child></Child>
</div>
</template>


<script>
import Child from "./Child.vue";

export default {
  components: {
    child: Child
  },
  methods: {
    addCounter() {
      this.$store.state.counter++;
    },
    subCounter() {
      this.$store.state.counter--;
    }
  }
};
</script>
// Child.vue
<template>
  <div>
    <hr>
    Child counter : {{ $store.state.counter }} <br>
    <button>+</button>
    <button>-</button>
  </div>
</template>



<script>
export default {};
</script>

 

 

 

 

 

**

그런데 에러가 생겼다

Child counter도 보이지 않는다

 

 

 

1. Parents.vue 의 template에서 <child></child>로 해주어야 한다 (오타)

// Parents.vue

<template>
<div id="app">
  Parent counter : {{ $store.state.counter }} <br>
  <button @click="addCounter">+</button>
  <button @click="subCounter">-</button>
  <child></child>
</div>
</template>


<script>
import Child from "./Child.vue";

export default {
  components: {
    child: Child
  },
  methods: {
    addCounter() {
      this.$store.state.counter++;
    },
    subCounter() {
      this.$store.state.counter--;
    }
  }
};
</script>

 

그러면 Child counter가 나타난다

 

갑자기 에러도 해결

원래는 <script>태그내에 있는 컴퍼넌트 속성에 컴퍼넌트를 추가하지 않아서 발생하는 문제라고 하는데

왜 갑자기 발생했고, 해결됐는지는 모르겠다

 

 

 

 

 

 

 

 

 

 

 

state에 counter 속성 추가 및 적용으로 달라진 건

  • data 속성으로 선언한 counter 값을 없애고
  • child component로 counter 값을 전달하지 않는 것이다

 

그러니까,

Parent 컴포넌트에서 관리하던 counter 데이터를 vuex의 state에 넘기면

⇒ Child 컴포넌트에서 접근하던 Parent component의 data 속성이 vuex로 갔기 때문에

⇒ Child에서는 vuex의 state를 보면 된다

⇒ Parent와 Child 모두 state를 접근 가능하게 됐고

⇒ 어떤 component든 이제 vuex로 counter를 접근할 수 있게 된 거다

 

어려 component간에 공유할 데이터를 효과적으로 다룰 수 있게 되었다는 의미.