[Vue.js] 컴포넌트 - Emit

OROSY·2021년 5월 3일
0

Vue.js

목록 보기
23/30
post-thumbnail
post-custom-banner

컴포넌트 - Emit

이번에는 컴포넌트의 emit 키워드에 대해 알아보도록 합시다. 더욱 자세한 사항은 공식 문서를 참고해주시기 바랍니다.

1. 이벤트 상속

App.vue(부모 컴포넌트)

<MyBtn @click="log">Banana</MyBtn>
export default {
  components: {
    MyBtn
  },
  methods: {
    log() {
      console.log('Click!!')
    }
  }
}

MyBtn.vue(자식 컴포넌트)

<div class="btn">
    <slot></slot>
</div>
export default {
  inheritAttrs: false
}

MyBtn 태그에 클릭 이벤트 시에 실행할 method를 연결하였습니다. 그러나 이또한 @click이라는 속성으로 연결을 하였기 때문에 자식 컴포넌트에 inheritAttrs: false 값으로 인해 클릭을 하여도 method가 실행되지 않습니다.

그렇다면, 자식 컴포넌트에 최상위 요소가 2개 이상이라면 inheritAttrs 옵션을 사용해야하는 경우가 있을 것이고 이렇게 된다면, 이벤트를 적용할 수 없을 것입니다.

이벤트도 이전 시간에 배운 $attrs와 비슷하게 필요한 경우에만 개별로 적용할 수 있습니다.

2. Emit

이렇게 이벤트 속성을 가능하게 만드는 것이 바로 emit입니다.

MyBtn.vue(자식 컴포넌트)

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

위와 같이 emits 라는 옵션을 추가하여 배열 데이터로 부모 컴포넌트에서 추가한 옵션인 클릭 이벤트를 사용하겠다고 명시하시면 됩니다.

MyBtn.vue(자식 컴포넌트)

<template>
  <h1 @click="$emit('click')">ABC</h1>
</template>

그리고 template 태그에 <h1 @click="$emit('click')"> click 옵션에 $emit이라는 메소드에 emits 옵션에 정의한 'click'을 입력해주시면 됩니다. 그러면 부모 컴포넌트(App.vue)에 정의한 log() 메소드가 실행되는 것을 확인할 수 있습니다.

3. 추가 코드 예시

이렇게 emit이라는 키워드를 통해 원하는 이름의 이벤트를 자유롭게 만들어 사용할 수 있습니다. 그리고 이를 활용하여 부모 컴포넌트와 자식 컴포넌트 간의 이벤트와 데이터를 주고 받을 수 있습니다.

아래의 예시를 통해 확인할 수 있으며, 익숙해지기 전에는 복잡해보일 수 있으나 실제로 사용하게 되면 간단한 로직이라 할 수 있습니다.

App.vue(부모 컴포넌트)

<template>
  <MyBtn
    @orosy="log"
    @change-msg="logMsg">
    Banana
  </MyBtn>
</template>
<script>
import MyBtn from '~/components/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 @dblclick="$emit('orosy', $event)">
    ABC
  </h1>
  <input
    type="text"
    v-model="msg" />
</template>
<script>
export default {
  emits: [
    'orosy',
    'changeMsg'
  ],
  data() {
    return {
      msg: ''
    }
  },
  watch: {
    msg() {
      this.$emit('changeMsg', this.msg)
    }
  }
}
</script>
profile
Life is a matter of a direction not a speed.
post-custom-banner

0개의 댓글