[Vue.js] 컴포넌트 통신

2021. 9. 20. 18:23개발공부/Vue.js 시작하기

728x90

컴포넌트 통신

컴포넌트는 재사용이 편한 기능으로 모듈화 시켜 사용할 수 있는 Vue의 핵심 기능입니다.

컴포넌트는 상위, 하위라는 속성을 통해 관계를 가지기 때문에 규칙이 존재합니다. 상위 컴포넌트가 데이터가 담긴 props를 내려주면 하위 컴포넌트는 event를 올려줍니다.

image

출처: 캡틴판교님 Cracking Vue.js

props를 적용시키면 상위 컴포넌트의 속성을 하위 컴포넌트로 내려줄 수 있습니다.

  <div id="app">
    <!-- <app-header v-bind:프롭스 속성 이름="상위 컴포넌트의 데이터 이름"></app-header> -->
    <app-header v-bind:propsdata="message"></app-header>
  </div>
  <script>
    var appHeader = {
        template: '<h1>header</h1>',
        props: ['propsdata']
    }

    new Vue({
        el: '#app',
        components: {
            'app-header': appHeader
        },
        data: {
            message: 'hi'
        }
});
  </script>

v-bind로 상위 컴포넌트의 데이터 이름을 하위 컴포넌트의 props 속성 이름에 바인딩 시켜줍니다. appHeader는 코드를 깔끔히 하려고 컴포넌트 데이터를 변수로 생성했습니다.

Vue의 reactivity(반응성) 특성을 이용해 상위 컴포넌트 변수가 변화할 때마다 하위 컴포넌트에서 변경을 감지해 화면에 반영하는 코드도 만들 수 있습니다.

  <script>
    var appHeader = {
      template: '<h1>{{ propsdata }}</h1>',
      props: ['propsdata']
    }

    var propsdata = 'anything you want!!!';

    new Vue({
      el: '#app',
      components: {
        'app-header': appHeader
      },
      data: {
        message: propsdata
      }
    })
  </script>

props는 지역 컴포넌트 내에서만 재사용 가능하기 때문에 props들끼리 props명을 다르게 만들어줄 필요는 없습니다.

  <div id="app">
    <!-- <app-header v-bind:프롭스 속성 이름="상위 컴포넌트의 데이터 이름"></app-header> -->
    <app-header v-bind:propsdata="message"></app-header>
    <app-content v-bind:propsdata="num"></app-content>
  </div>
  <script>
    var appHeader = {
      template: '<h1>{{ propsdata }}</h1>',
      props: ['propsdata']
    }
    var appContent = {
      template: '<div>{{ propsdata }}</div>',
      props: ['propsdata']
    }

      var message = 'anything you want!!!';
      var num = 10;

      new Vue({
          el: '#app',
      components: {
          'app-header': appHeader,
          'app-content': appContent
      },
      data: {
          message: message,
          num: num
     }
   });
  </script>

반대로 하위 컴포넌트에서 이벤트가 발생됐을때 그것을 event emit이라 부르는데, 코드는 다음과 같습니다.

  <script>

    var appHeader = {
        template: '<button v-on:click="passEvent">click me</button>',
        methods: {
        passEvent: function() {
            this.$emit('pass');
                    }
                }
            }
  </script>

methods는 컴포넌트의 메서드를 추가하는 key값 입니다. this.$emit은 이벤트를 발생시키는 명령어입니다. 코드에서는 'pass'라는 이벤트를 발생시키고 있습니다.

브라우저에서 크롬 Vue 익스텐션을 통해 확인하면 이벤트가 발생되었을 때 name, type, source, payload라는 하위 컴포넌트에서 발생한 이벤트 정보들이 출력되는 것을 볼 수 있습니다.

상위 컴포넌트에 이벤트가 발생했다는 것을 넘겨주면 메서드를 전달해줍니다.

  <div id="app">
    <!-- <app-header v-on:하위 컴포넌트에서 발생한 이벤트 이름="상위 컴포넌트 메서드 이름"></app-header> -->
    <app-header v-on:pass="logText"></app-header>
  </div>
  <script>
    new Vue({
        el: '#app',
        components: {
            'app-header': appHeader
        },
        methods: {
            logText: function() {
                console.log('hi');
            }
        }
    });
  </script>

v-on으로 이벤트명을 바인딩 해주고 실행시킬 상위 컴포넌트 메서드명을 추가해주는 방식은 props할 때 사용한 v-bind:하위 컴포넌트 이름="상위 데이터 이름" 형식과 같습니다.

image

같은 방식으로 클릭 시 num을 1씩 증가시켜주는 메서드를 생성해보겠습니다. 이때 this가 사용됩니다.


  <div id="app">
    <p>{{ num }}</p>
    <!-- <app-header v-on:하위 컴포넌트에서 발생한 이벤트 이름="상위 컴포넌트 메서드 이름"></app-header> -->
    <app-header v-on:pass="logText"></app-header>
    <app-content v-on:increase="addNumber"></app-content>
  </div>

  <script>
    var appContent = {
        template: '<button v-on:click="addNumber">add</button>',
        methods: {
            addNumber: function() {
                this.$emit('increase');
            }
        }
    }

    new Vue({
      el: '#app',
      components: {
        'app-header': appHeader,
        'app-content': appContent
      },
      methods: {
        logText: function() {
          console.log('hi');
        },
        addNumber: function() {
          console.log(++this.num);
        }
      },
      data: {
        num: 10
      }
    });
  </script>

{{ num }}은 this.num을 화면서 표시해줍니다. this는 현재 변수/객체를 바라보게 해주며 뒤에 나오는 this.변수명은 현재 바라보는 변수/객체 범위 내에서 초기화된 변수를 가리킵니다.

this는 Java에서 쓰는 용법과 같아서 참고자료 링크만 간단히 훑고가면 좋을듯 싶습니다.


참고자료: