IT/development

[Vue.js] event emit(자식 → 부모)

알 수 없는 사용자 2023. 7. 26. 06:37
반응형

하위(자식)컴포넌트에서 상위(부모) 컴포넌트로 데이터 전달 시 사용하는 속성

//하위컴포넌트인 app-header에 click 이벤트(v-on:click을 @click으로 표현 가능)를 설정
let appHeader = {
  template: '<button @click="passEvent">click me</button>',
        //methods 속성에 리벤트 핸들러를 생성 후 this.$emit('이벤트명')으로 이벤트 발생 시킴
  //해당 이벤트는 부모 컴포넌트에서 감지해서 처리 가능
  methods: {
      passEvent: function() {
          this.$emit('pass');
      }
  },  
}

new Vue({
    el: '#app',
    components: {
        'app-header': appHeader,
    },
})
<body>

<div id="app">
<app-header></app-header>
</div>

결과

버튼 클릭 시 pass라는 이벤트가 발생하는 것 확인됨

부모에서 자식의 이벤트 발생 감지

let appHeader = {
  template: '<button @click="passEvent">click me</button>',
  methods: {
      passEvent: function() {
          this.$emit('pass');
      }
  },  
}       

new Vue({
  el: '#app',
  components: {
      'app-header': appHeader,
  },
  methods: {
                //자식의 이벤트 발생 시 실행시킬 부모 컴포넌트의 메소드
      logText: function() {
          console.log("자식에서 이벤트가 올라왔다.");
      }
  }
})
<div id="app">
    <!-- v-on:자식컴포넌트의 이벤트명="부모컴포넌트의 함수명" -->
<app-header v-on:pass="logText"></app-header>
</div>

결과

자식 컴포넌트 이벤트 발생 시 부모 컴포넌트의 데이터 변경

<div id="app">
    <!-- 자식의 이벤트명인 'add' 발생 시 부모컴포넌트의 plusNum() 실행 --> 
<app-content v-on:add="plusNum"></app-content>
</div>
//하위 컴포넌트
let appContent = {
  template: '<button @click="addNumber">add</button>',
  methods: {
      addNumber: function() {
                        //'add'라는 이벤트명으로 이벤트 발생(부모에서 감지 가능)
          this.$emit('add');
      }                
  }
}   

new Vue({
  el: '#app',
  components: {
      'app-header': appHeader,
      'app-content': appContent,
  },
  methods: {
      logText: function() {
          console.log("자식에서 이벤트가 올라왔다.");
      },
      plusNum: function() {
                        //이 안에서의 this는 해당 컴포넌트 인스턴스를 가리킴
          this.num ++;
                        //num++   <-- 이 코드는 ReferenceError: num is not defined 발생
      }
  },
  data: {
      num: 10,
  }
})

결과

같은 레벨의 컴포넌트끼리 데이터 전달

<div id="app">
    <!-- app-header에 전달하 propsdata를 부모의 num을 전달 -->
<app-header v-bind:propsdata="num"></app-header>
<!-- 자식의 pass 이벤트 발생 시 부모의 deliverNum 함수 실행 -->
<app-content v-on:pass="deliverNum"></app-content>
</div>
let appHeader = {
  template: '<div>header</div>',
  props: ['propsdata'],
}           

let appContent = {
  template: '<div>content<button @click="passNum">pass</button></div>',
  methods: {
      passNum: function() {
          //1.'pass'라는 이벤트를 발생 시킬 때 2번 째 인자값으로 전달할 데이터 설정    
          this.$emit('pass', 10); 
      }   
  },      
}

new Vue({
  el: '#app',
  components: {
      'app-header': appHeader,
      'app-content': appContent,
  },
  methods: { 
                //2.appContent의 passNum()에서 넘긴 10을 부모의 
                //deliverNum()에서 인자값으로 받을 수 있고 이를 부모의 데이터에 치환
      deliverNum: function(value) {   
          this.num = value;
      },
  },  
  data: {
      num: 0,    
  }
})

결과

Root 초기값이 10으로 변경되었고 app-header의 propsdata도 10이 잘 전달 되었음

reference: https://www.inflearn.com/course/age-of-vuejs/dashboard

 

Vue.js 시작하기 - Age of Vue.js - 인프런 | 강의

Vue.js로 쉽게 웹 개발할 수 있도록 기본 개념과 핵심 기능에 대해서 학습하고 구현해봅니다. 강좌를 들으시고 나면 Vue.js로 프런트엔드 개발을 하시는게 재밌어질거에요., [사진] Vue.js 시작하기,Ag

www.inflearn.com

반응형