VueJS에서 부모와 자식 컴포넌트 사이에 데이터를 서로 주고 받는 양방향 바인딩(Two way binding) 방법에 대하여 알아봅니다.


먼저 컴포넌트 사이의 데이터를 주고 받는 방법은 여러가지가 있습니다. 전역 데이터를 사용하거나, 이벤트버스(EventBus), Vuex 아니면 Props를 사용할 수도 있죠. 여기서 Props를 사용하는 방법이 많이 사용되는데요 ~


! Props를 사용한 컴포넌트간의 데이터 전송방법
부모, 자식 컴포넌트 사이에 Props를 사용하면 부모에서 자식으로 데이터를 전송할 수 있지만 반대로 자식에서 부모로 전달할 수 없는 문제가 생깁니다. 그럼 어떻게하면 해결할 수 있는지 아래에서 알아봅니다.

(참고사항. Vue 2 이전에는 props를 사용하여 동일한 스코프 모델명을 사용하면 서로 양방향 데이터 전송이 가능했다고 합니다. 하지만 Deprecated 되어 현재는 불가능합니다.)



# 부모 자식 컴포넌트 Props 사용시 양방향 바인드 구현하기
그럼 예제를 하나 만들어보겠습니다. 아래는 두 개의 컴포넌트가 부모와 자식으로 존재합니다.

@ testComponent.vue
<template>
  <div>
    {{ myNum }}
    <PressNumber v-bind:myNum="myNum" />
  </div>
</template>

<script>
export default {
  name : 'testComponent',
  data: function() {
    return {
      myNum : 10
    }
  },
  methods : {
    updateParentNumber: function(num) {
      this.myNum = num;
    }
  }
}  
</script>

여기서 부모인 testComponent는 myNum이라는 값을 자식 요소에 전달하고 자식 요소는 새로운 값으로 변경할 수 있는 입력폼을 가지고 있습니다. 즉 자식에서 값을 변경해도 부모가 가진 myNum이 변경되어 새로운 값이 출력되도록 만들려고 합니다.

하지만 위 코드만으로는 현재 값 myNum을 자식 컴포넌트 PressNumber에 전달만 하였을 뿐 자식 요소에서 업데이트시 부모가 이를 전달 받을 수 없습니다. 그래서 아래와 같이 코드를 부모의 이벤트를 호출할 수 있도록 코드를 업데이트 하였습니다.


@ PressNumber.vue
<template>
  <div>
    <input type="number" v-model="propMyNum" @keyup="updateNumber" />
  </div>
</template>

<script>
export default {
  props : ['myNum'],
  data: function() {
    return {
      propMyNum: this.myNum
    }
  },
  methods : {
    updateNumber: function() {
      this.$emit('updateParentNumber', this.propMyNum);
    }
  }
}  
</script>

위 코드는 자식 컴포넌트의 코드입니다. 자식 컴포넌트에서 값이 업데이트 되면 updateNumber() 함수를 호출합니다. 여기서 새로운 값으로 바뀐 propMyNum를 부모에게 전달하기 위해서 $emit()이 사용됩니다.


! $emit 어떤 동작을 하는가
$emit은 부모 컴포넌트가 가진 메소드를 호출할 수 있으며 이때 값을 전달할 수도 있습니다. 즉 아래의 코드를 보시면...
this.$emit('updateParentNumber', this.propMyNum);

부모의 updateParentNumber 메소드를 호출하고 이때 전달할 값으로 this.propMyNum를 인자로 넘기게 되는 것입니다. 그래서 부모가 가진 updateParentNumber 메소드에서 전달 받은 값으로 변경되어 출력되게 됩니다. 



# 마치면서 정리하기
여기까지 props를 사용하여 부모 자식 양방향 사이에 데이터를 전달하는 방법을 알아보았습니다. 다시 한 번 정리하면 아래와 같은 순서로 동작하게 됩니다.

1. v-bind를 사용하여 props 부모와 자식 컴포넌트 데이터 전달
2. 자식 요소에서 값이 변경되면 $emit 사용
3. 사용된 $emit으로 부모 메소드 호출하며 값을 전달
4. 부모 메소드에서 이벤트로 전달 받은 값으로 업데이트
5. 완료

하나씩 나누어서 생각하면 더 쉽고 간단합니다.