완벽하게 Vue.js

[Vue.js][Ch2][Vue 문법] 컴포넌트 - Emit

써치킴 2022. 4. 18. 20:37

Emit

다른 컴포넌트에게 이벤트를 전달하기 위해 사용.

특정한 이벤트를 상속받아서 emits 옵션에 연결해서 사용.

 

1. emits 속성에 click 이벤트를 컴포넌트 내부에서 사용할 것이라고 정의

<script>
export default {
  emits: [  
    'click'   // 부모 요소의 click 이벤트를 컴포넌트 내부에서 사용할 것이라고 정의
  ]
}
</script>

2. click 이벤트를 어떤 부분에 연결할 것인지 정함 -> h1 요소에 연결하겠음

<template>
  <div class="btn"> 
    <slot></slot>
  </div>
  <!-- h1 태그를 클릭하면 $emit을 통해서 부모 요소에 연결되어 있는 @click 이벤트 실행 -->
  <h1 @click="$emit('click')">
    ABC
  </h1>
</template>
  • h1 태그를 클릭하면 emit 메소드를 실행하겠다.

부모 요소의 click 이벤트를 가져와서 emits 속성에 명시 -> 명시된 내용을 요소의 emit 부분에 명시

 

App.vue

<template>
  <MyBtn @click="log">
    Banana
  </MyBtn>
</template>

<script>
import MyBtn from '~/components/Ex15_MyBtn'

export default {
  components: {
    MyBtn
  },
  methods: {
    log() {
      console.log('Click!');
    }
  }
}
</script>

MyBtn.vue

<template>
  <div class="btn"> 
    <slot></slot>
  </div>
  <!-- h1 태그를 클릭하면 $emit을 통해서 부모 요소에 연결되어 있는 @click 이벤트 실행 -->
  <h1 @click="$emit('click')">
    ABC
  </h1>
</template>

<script>
export default {
  emits: [  
    'click'   // 부모 요소의 click 이벤트를 컴포넌트 내부에서 사용할 것이라고 정의
  ]
}
</script>


<style scoped lang="scss">
 .btn {
   display: inline-block;
   margin: 4px;
   padding: 6px 12px;
   border-radius: 4px;
   background-color: gray;
   color: white;
   cursor: pointer;
   &.large {
   font-size: 20px;
   padding: 10px 20px;
  }
 }
</style>

출력

 

 

 

 

 

Banana를 클릭하면 아무런 동작이 없지만

ABC를 클릭하면 Click!이 콘솔에 출력된다.

 

 

 

 

 

 

 

컴포넌트에 연결하는 이벤트는 실제로 사용하는 이벤트가 아니여도 상관없다.

@click -> @searchkim 으로 사용 가능하다.

요소에 실제 동작하는 이벤트도 사용 가능하다.

<template>
  <div class="btn"> 
    <slot></slot>
  </div>
  <!-- h1 태그를 더블클릭하면 $emit을 통해서 부모 요소에 연결되어 있는 @searchkim 이벤트 실행 -->
  <h1 @dblclick="$emit('searchkim')">
    ABC
  </h1>
</template>

@dlbclick 이벤트 사용 -> 더블 클릭을 하면 콘솔에 Click!가 출력된다.

event 객체를 사용하려면

$emit 메소드에 event 객체를 인수로 전달

 

App.vue

<template>
  <MyBtn @searchkim="log">
    Banana
  </MyBtn>
</template>

<script>
import MyBtn from '~/components/Ex15_MyBtn'

export default {
  components: {
    MyBtn
  },
  methods: {
    log(event) {
      console.log('Click!');
      console.log(event);
    }
  }
}
</script>

MyBtn.vue

<template>
  <div class="btn"> 
    <slot></slot>
  </div>
  <!-- h1 태그를 클릭하면 $emit을 통해서 부모 요소에 연결되어 있는 @searchkim 이벤트 실행 -->
  <h1 @dblclick="$emit('searchkim', $event)">
    ABC
  </h1>
</template>

<script>
export default {
  emits: [  
    'searchkim'   // 부모 요소의 searchkim 이벤트를 컴포넌트 내부에서 사용할 것이라고 정의
  ]
}
</script>


<style scoped lang="scss">
 .btn {
   display: inline-block;
   margin: 4px;
   padding: 6px 12px;
   border-radius: 4px;
   background-color: gray;
   color: white;
   cursor: pointer;
   &.large {
   font-size: 20px;
   padding: 10px 20px;
  }
 }
</style>

출력

특정 요소가 변경될때마다 그 내용을 App.vue에서 확인하고 싶다면?

양방향 데이터 바인딩 구조에서 emit 사용

 

App.vue

<template>
  <!--  html의 속성을 작성할때는 대시 케이스 사용(change-msg) -->
  <MyBtn 
  @searchkim="log" 
  @change-msg="logMsg">
    Banana
  </MyBtn>
</template>

<script>
import MyBtn from '~/components/Ex15_MyBtn'

export default {
  components: {
    MyBtn
  },
  methods: {
    log(event) {
      console.log('Click!');
      console.log(event);
    },
    logMsg(msg) {
      console.log(msg);
    }
  }
}
</script>

MyBtn.vue

<template>
  <div class="btn"> 
    <slot></slot>
  </div>
  <!-- h1 태그를 클릭하면 $emit을 통해서 부모 요소에 연결되어 있는 @click 이벤트 실행 -->
  <h1 @dblclick="$emit('searchkim', $event)">
    ABC
  </h1>
  <input
    type="text"
    v-model="msg" />    <!-- 양방향 데이터 바인딩 -->
</template>

<script>
export default {
  emits: [  
    'searchkim',   // 부모 요소의 searchkim 이벤트를 컴포넌트 내부에서 사용할 것이라고 정의
    'changeMsg'    // changeMsg 이벤트를 사용하겠다 명시
  ],
  data() {
    return {
      msg: ''
    }
  },
  watch: {
    msg() {     // msg 감시
      // input 요소에 데이터를 입력할 때마다 this.$emit을 통해서 this.msg 인수와 함께 changeMsg 실행
      this.$emit('changeMsg', this.msg);    
    }
  }
}
</script>


<style scoped lang="scss">
 .btn {
   display: inline-block;
   margin: 4px;
   padding: 6px 12px;
   border-radius: 4px;
   background-color: gray;
   color: white;
   cursor: pointer;
   &.large {
   font-size: 20px;
   padding: 10px 20px;
  }
 }
</style>

출력

input 요소에 데이터를 입력할 때마다 msg 데이터가 양방향 데이터 방식으로 갱신되는 구조이고, watch 옵션을 통해 감시한다.

watch 옵션에서 실행되는 명령은 $emit 메소드를 통해 changeMsg 이벤트가 발생하고, 명시해놓은 logMsg가 발생한다.