개발 도구 (Development Tools)/Vue

Vue - 사용자 지정 이벤트(Custom Event)

BiCute 2023. 1. 19. 08:00
반응형

 

Vue에서는 사용자 지정 이벤트를 사용하여 서로 다른 컴포넌트 간에 통신할 수 있습니다.

템플릿에서 사용자 지정 이벤트를 내보내려면 $emit메서드를 사용하여 이벤트 이름과 이벤트에 포함할 페이로드를 전달할 수 있습니다.

 

아래는 $emit 메서드를 이용하여 자식 컴포넌트가 부모 컴포넌트에게 데이터를 전달하거나 데이터를 변경하도록 요청하는 방법들입니다.

 

 

# 템플릿에서 이벤트를 요청

$emit 메서드를 사용하여 이벤트 이름과 이벤트에 포함할 페이로드를 전달할 수 있습니다.

// 자식 컴포넌트의 템플릿에서 사용자 지정 이벤트를 요청
<template>
  <button @click="$emit('my-custom-event', { message: 'Hello, world!' })">
    Click me
  </button>
</template>

 

 

# 스크립트에서 이벤트를 요청

this.$emit 메서드를 사용하여 컴포넌트의 스크립트 태그에서 사용자 지정 이벤트를 내보낼 수도 있습니다 .

// 자식 컴포넌트의 스크립트 태그에서 사용자 지정 이벤트를 요청
export default {
  methods: {
    handleClick() {
      this.$emit('my-custom-event', { message: 'Hello, world!' });
    }
  }
}

 

 

# v-on 지시문으로 이벤트를 수신

자식 컴포넌트에서 보낸 사용자 지정 이벤트를 수신하려면 v-on지시문을 사용하고 수신하려는 이벤트의 이름을 작성하여 바인딩 할 수 있습니다.

// 부모 요소는 v-on을 사용해 이벤트를 수신
<template>
  <child-component v-on:my-custom-event="handleCustomEvent"></child-component>
</template>

<script>
export default {
  methods: {
    handleCustomEvent(payload) {
      console.log(payload.message); // "Hello, world!"
    }
  }
}
</script>

 

 

# @로 이벤트를 수신

v-on:은 @로 줄여 쓸 수 있습니다

// v-on은 아래와 같이 @를 이용해 사용할 수 있음
<template>
  <child-component @my-custom-event="handleCustomEvent"></child-component>
</template>

<script>
export default {
  methods: {
    handleCustomEvent(payload) {
      console.log(payload.message); // "Hello, world!"
    }
  }
}
</script>

 

 

# Payload란?

 

페이로드는 이벤트와 함께 전달하는 데이터이며, 모든 유형의 데이터를 사용할 수 있습니다.
예를 들어 아래 예는 $emit을 이용하여 자식 컴포넌트에서 부모 컴포넌트로 메시지를 보내는 데 사용하고 있습니다.

<template>
  <button @click="$emit('send-message', 'Hello, world!')">Click me</button>
</template>

 

위 예에서 자식 컴포넌트는 라는 사용자 지정 이벤트 send-message를 보내고, 데이터(Hello, world!라는 문자열)을 페이로드로 전달합니다.

부모 컴포넌트는 이 이벤트를 수신하고 methods를 사용하여 페이로드에 액세스할 수 있습니다 .

<template>
  <child-component v-on:send-message="handleMessage"></child-component>
</template>

<script>
export default {
  methods: {
    handleMessage(message) {
      console.log(message); // "Hello, world!"
    }
  }
}
</script>

 

페이로드는 여러 데이터를 포함하는 객체일 수도 있습니다.

// 자식 컴포넌트
<template>
  <button @click="$emit('send-message', { message: 'Hello, world!', sender: 'Child component' })">Click me</button>
</template>

이와 같은 경우 페이로드는 message및 sender라는 두 가지 속성을 포함하는 객체입니다.
부모 구성 요소는 점(.) 표기법을 사용하여 이러한 속성에 액세스할 수 있습니다.

 

// 부모 컴포넌트
<template>
  <child-component v-on:send-message="handleMessage"></child-component>
</template>

<script>
export default {
  methods: {
    handleMessage(payload) {
      console.log(payload.message); // "Hello, world!"
      console.log(payload.sender); // "Child component"
    }
  }
}
</script>

 

$emit를 사용하여 사용자 지정 이벤트를 내보낼 때 문자열, 숫자, 개체, 배열 등 모든 유형의 데이터를 페이로드로 전달할 수 있습니다 . 

 

 

 

# emit을 사용할 때 자주 볼 수 있는 경고 해결하기

 

경고문

[Vue warn]: Extraneous non-emits event listeners (item) were passed to component but could not be automatically inherited because component renders fragment or text root nodes. If the listener is intended to be a component custom event listener only, declare it using the "emits" option.

 

 

해결 방법

요청을 하는 자식 요소의 스크립트에 emits 항목을 추가해 줍니다.

// 자식 요소의 스크립트에 emits 추가
export default {
  emits: ['my-custom-event'],
  methods: {
    handleClick() {
      this.$emit('my-custom-event', { message: 'Hello, world!' });
    }
  }
}

 

요청하는 이벤트가 여러개 일경우 아래와 같이 배열처럼 이벤트 이름을 작성해 줍니다.

// 요청하는 이벤트가 여러개일 경우 아래와 같이 각각의 이벤트를 배열처럼 작성
export default {
  emits: ['my-custom-event1', 'my-custom-event2', 'my-custom-event3'],
  methods: {
    handleClick1() {
      this.$emit('my-custom-event1', { message: 'Hello, HTML!' });
    },
    handleClick2() {
      this.$emit('my-custom-event2', { message: 'Hello, CSS!' });
    },
    handleClick3() {
      this.$emit('my-custom-event3', { message: 'Hello, JavaScript!' });
    }
  }
}

 

위 방법으로도 경고문이 해결이 되지 않는다면 이제는 사용되지 않는 emits가 부모 요소에 정의되어 있지는 않는지 확인해 봅시다.

반응형