본문 바로가기
Front-end/Vue3

22. Vue - Emit(1)

by devraphy 2021. 5. 24.

1. Emit 이란? 

- 이전 시간에 속성 상속에 대해서 배워보았다.

- 속성 상속은 최상위 컴포넌트가 하나 이상인 경우, 속성을 직접 컴포넌트에 할당하는 것을 의미한다. 

- 이와 비슷하게 Emit은 최상위 컴포넌트가 하나 이상인 경우, 이벤트를 직접 컴포넌트에 할당하는 것을 의미한다. 

- 어떻게 하는지 예제코드를 통해서 알아보자. 

 

a) 예제코드

[App.vue]

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

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

 

[MyBtn.vue]

<template>
  <div
    class="btn">
    <slot></slot>
  </div>
  <h1></h1>
</template> 

<script>
export default {
}
</script>

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

- MyBtn.vue를 살펴보면 최상위 컴포넌트가 div와 h1 두가지 이다. 

- log 라는 이벤트를 등록해 놓았으나, 최상위 컴포넌트가 두개이므로 작동하지 않는다. 

- Emit을 이용하여 직접 이벤트를 할당하는 방법을 알아보자. 

 

 

b) Emit 적용하기

[MyBtn.vue]

<template>
  <div
    class="btn">
    <slot></slot>
  </div>
  <h1 @click="$emit('click')">
    h1태그 입니다.
  </h1>
</template> 

<script>
export default {
  emits: [
    '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;
  }
</style>

- script 태그에 emits이라는 속성값을 이용하여 'click' 이라는 이름의 메소드를 등록하였다. 

- emits를 쓸 때, s가 붙는 것을 빼먹지 말자!

- 이로써 Emit에 'click'이라는 이름의 이벤트가 등록되었다. 

- h1 태그를 클릭하면 해당 이벤트가 동작하도록 만들어 보자.

- h1 태그에 click 이벤트 핸들러를 등록하고, 그 안에 $emit을 이용하여 Emit에 등록해놓은 이벤트를 사용한다. 

- emit을 이용한 특정 컴포넌트의 이벤트 할당이 완료되었다.  

 

[출력화면]

 

c) 어떻게 동작하는 걸까?

- 위의 코드를 보면, 분명 App.vue에 등록해놓은 이벤트 메소드의 이름은 log()다. 

- 하지만, MyBtn.vue의 script 태그 부분에서 emits에 작성한 이름은 'click' 이다.

- 이를 기반으로 확인할 수 있는 부분은, 이벤트 메소드의 이름으로 동작하는 것이 아니라, 이벤트의 이름으로 등록하는 것이다. 

- click 이벤트로 동작하는 메소드라면 'click' 이벤트를 emit에 등록해야 한다는 것이다. 

- 다음 응용 예제를 살펴보자. 


2. emit으로 등록된 이벤트를 다른 이벤트로 사용하기

a) 예제코드

[App.vue]

<template>
  <MyBtn @testEvent="log">
    Banana?
  </MyBtn>
</template>

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

 

[MyBtn.vue]

<template>
  <div
    class="btn">
    <slot></slot>
  </div>
  <h1 @click="$emit('testEvent')">
    h1태그 입니다.
  </h1>
</template> 

<script>
export default {
  emits: [
    'testEvent'
  ]
}
</script>

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

 

[출력화면]

 

- App.vue를 살펴보면 testEvent라는 이름의 이벤트를 등록하였다. 

- MyBtn.vue를 살펴보면 script 태그의 emit 속성값에서 testEvent라는 이름을 등록해놓았다. 

- 그리고 결과를 살펴보면, 이전과 동일하게 h1태그를 클릭해도 이벤트 메소드가 잘 동작하는 것을 확인할 수 있다. 

- 이유가 무엇일까? 

 

- MyBtn.vue를 살펴보면 template 태그의 h1태그에 @click 이벤트를 등록해 놓은 것을 알 수 있다. 

- 즉, App.vue에 등록해놓은 이벤트의 종료와는 상관없이 해당 이벤트에 연결되어 있는 이벤트 메소드만 emit을 통해서 동작된다는 것을 확인할 수 있는 것이다.   

 

b) emit으로 등록된 이벤트를 다른 이벤트로 사용하기

클릭하면 확대됩니다.

- 위의 사진을 살펴보면 App.vue에서 keydown 이벤트를 등록한 것을 알 수있다. 

- 하지만, emit에 등록한 후, 이를 컴포넌트에 할당할 때에는 click 이벤트로 할당하였다. 

- 아래의 출력화면과 같이 클릭이벤트로 해당 keydown이벤트가 동작하는 것을 확인할 수 있다. 

 

[출력화면]

 

'Front-end > Vue3' 카테고리의 다른 글

24. Vue - slot 태그  (0) 2021.05.25
23. Vue- Emit(2)  (0) 2021.05.24
21. Vue - 속성 상속  (0) 2021.05.21
20. Vue - 컴포넌트 기초(props, slot)  (0) 2021.05.21
19. Vue - V model 수식어  (0) 2021.05.21

댓글