Miracle Morning, LHWN

2. 뷰 컴포넌트 통신 본문

IT 기술/[Vue] 기본

2. 뷰 컴포넌트 통신

Lee Hye Won 2021. 6. 1. 14:50
컴포넌트 간 통신과 유효범위

 

뷰는 여러 컴포넌트로 화면을 구성하는데, 각 컴포넌트의 유효 범위가 독립적이기 때문에 다른 컴포넌트의 값을 직접적으로 참조할 수 없다.

따라서 뷰 프레임워크 자체에서 정의한 데이터 전달 방법인 '상위(부모) - 하위(자식) 컴포넌트 간의 데이터 전달 방법'을 따라야 한다.

 


지역 혹은 전역 컴포넌트를 등록하면,
등록된 컴포넌트는 하위 컴포넌트가 되고
하위 컴포넌트를 등록한 인스턴스는 상위 컴포넌트가 된다.

https://jamong-icetea.tistory.com/194

 

상위 → 하위 : props 라는 속성을 전달

하위 → 상위 : 이벤트만 전달 가능

 

상위에서 하위 컴포넌트로 데이터 전달하기

 

// 상위 컴포넌트
<child-component v-bind:propsdata="message"></child-component>
...
// 하위 컴포넌트
// Vue.component() 이용하여 하위 컴포넌트인 child-cmoponent 를 등록
Vue.component('child-component', {
  props: ['propsdata'], // props 속성으로 propsdata 를 정의
  template: '<p>{{ propsdata }}</p>'
});

// new Vue 로 인스턴스 생성
new Vue({
  el: '#app',
  data: {
    message: 'Hello! Vue'
  }
});

→ 뷰 인스턴스의 data 속성에 정의된 message 속성을 하위 컴포넌트에 props 로 전달하여 화면에 출력

 

하위에서 상위 컴포넌트로 이벤트 전달하기

 

# 이벤트 발생과 수신 형식

// 이벤트 발생 (하위 컴포넌트의 특정 메서드에서 발생 → this 는 하위 컴포넌트를 가리킴)
this.$emit('이벤트명');

// 이벤트 수신
<child-component v-on:이벤트명="상위 컴포넌트의 메서드명"></child-component>
<div id="app">
  <child-component v-on:show-log="printText"></child-component> // 3. show-log 의 대상 메서드인 최상위 컴포넌트의 메서드 printText() 실행
</div>
...
<script>
  Vue.component('child-component', {
  template: '<button v-on:click="showLog">show</button>', // 1. show 버튼 클릭 시 showLog() 메서드 실행 
  methods: {
    showLog: function() {
      this.$emit('show-log'); // 2. show-log 이벤트 발생
    }
  }
});

var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue! passed from Parent Component'
  },
  methods: {
    printText: function() {
      console.log("received an event");
    }
  }
});
</script>

 

같은 레벨의 컴포넌트 간 통신

 

뷰는 상위에서 하위로만 데이터를 전달해야 하는 기본적인 통신 규칙을 따르기 때문에 바로 옆 컴포넌트에게 값을 전달하려면

하위에서 공통 상위 컴포넌트로 이벤트를 전달한 후 공통 상위 컴포넌트에서 2개의 하위 컴포넌트에 props 를 내려 보내야 한다.

하지만, 이런 통신 구조를 유지하다보면 상위 컴포넌트가 필요 없어도 그저 같은 레벨 간 통신을 위해 상위 컴포넌트를 두어야 한다.

이를 해결할 수 있는 방법이 이벤트 버스이다.

 

관계 없는 컴포넌트 간 통신 : 이벤트 버스

 

# 이벤트 버스 형식

- 보내는 컴포넌트에서는 .$emit()

- 받는 컴포넌트에서는 .$on()

 

// 이벤트 버스 위한 추가 인스턴스 1개 생성 (애플리케이션 로직을 담는 인스턴스와는 별개)
var eventBus = new Vue();

// 이벤트 보내는 컴포넌트
methods: {
  메서드명: function() {
    eventBus.$emit('이벤트명', 데이터);
  }
}

// 이벤트를 받는 컴포넌트
methods: {
  created: function() {
    eventBus.$on('이벤트명', function(데이터) {
      ...
    });
  }
}

 

# 이벤트 버스 구현 예시

<script>
  var eventBus = new Vue(); // 이벤트 버스로 활용할 새 인스턴스
  Vue.component('child-component', {
    template: '<div>하위 컴포넌트 영역입니다. <button v-on:click="showLog">show</button></div>',
    methods: {
      showLog: function() {
        eventBus.$emit('triggerEventBus', 100); // triggerEventBus 발생하는 로직 추가. 발생할 때 수신하는 쪽에 인자 값으로 100 이라는 숫자를 함께 전달
      }
    }
});

var app = new Vue({
  el: '#app',
  created: function() {
    eventBus.$on('triggerEventBus', function(value) { // 이벤트를 받는 로직. 
      console.log('이벤트를 전달받음. 전달받은 값 : ", value);
    });
  }
});
</script>

 

Comments