✏️ Vue 3: `defineExpose` vs `defineEmits`, 그리고 이벤트 vs 함수 차이

ZYE KIM·2025년 2월 24일
0

Tech Log

목록 보기
3/6
post-thumbnail

Vue 3에서는 defineExposedefineEmits를 사용해 컴포넌트 간 데이터 및 기능을 전달할 수 있다. 이를 이해하려면, 먼저 이벤트(event)와 함수(function)의 차이를 알아야 한다.


1️⃣ 이벤트(event) vs 함수(function)

🎯 함수란?

  • 특정 로직을 실행하는 코드 블록
  • 직접 호출해야 실행됨 (함수명())
  • 독립적인 동작 수행 가능
✅ 함수 예제
function sayHello() {
  console.log("안녕하세요!");
}

sayHello(); // 직접 호출

➡️ sayHello()를 호출해야 콘솔에 "안녕하세요!"가 출력됨.

🎯 이벤트란?

  • 특정 상황(클릭, 입력 등)이 발생했을 때 실행됨
  • 브라우저나 사용자의 동작에 의해 자동으로 실행됨
  • 이벤트 리스너를 등록해야 함
✅ 이벤트 예제
document.getElementById("btn").addEventListener("click", function () {
  console.log("버튼이 클릭됨!");
});

➡️ 버튼을 클릭해야 "버튼이 클릭됨!"이 출력됨. 직접 호출하지 않아도 이벤트가 발생하면 자동 실행됨.

🔥 이벤트와 함수의 연결

  • 이벤트는 특정 상황이 발생하면 실행되지만, 그 안에서 실행되는 것은 결국 함수이다.
  • 즉, 이벤트는 트리거(Trigger) 역할을 하고, 함수는 실제 동작을 수행하는 역할을 한다.
function handleClick() {
  console.log("버튼이 눌렸습니다!");
}

document.getElementById("btn").addEventListener("click", handleClick);

➡️ 클릭하면 handleClick() 함수가 실행됨.


2️⃣ defineExpose vs defineEmits

🎯 defineExpose: 부모가 자식의 특정 메서드 직접 호출

defineExpose자식 컴포넌트의 메서드(함수)나 데이터(변수)를 부모가 직접 접근할 수 있도록 한다.

defineExpose 예제
📌 자식 컴포넌트 (ChildComponent.vue)
<script setup>
import { defineExpose } from "vue";

const sayHello = () => {
  console.log("안녕하세요!");
};

defineExpose({
  sayHello,
});
</script>

<template>
  <p>자식 컴포넌트</p>
</template>
📌 부모 컴포넌트 (Parent.vue)
<template>
  <ChildComponent ref="childRef" />
  <button @click="callChildMethod">자식 함수 호출</button>
</template>

<script setup>
import { ref } from "vue";
import ChildComponent from "./ChildComponent.vue";

const childRef = ref(null);

const callChildMethod = () => {
  if (childRef.value) {
    childRef.value.sayHello(); // ✅ 부모에서 직접 자식 함수 호출
  }
};
</script>

➡️ 부모가 ref를 이용해 자식의 sayHello() 메서드를 직접 실행할 수 있음.


🎯 defineEmits: 자식이 부모에게 이벤트 전달

defineEmits자식이 부모에게 데이터를 전달할 때 사용된다. 부모는 해당 이벤트를 감지해 핸들러를 실행할 수 있다.

defineEmits 예제
📌 자식 컴포넌트 (ChildComponent.vue)
<script setup>
import { defineEmits } from "vue";

const emit = defineEmits(["customEvent"]);

const notifyParent = () => {
  emit("customEvent", "자식이 보낸 데이터!");
};
</script>

<template>
  <button @click="notifyParent">부모에게 이벤트 전송</button>
</template>
📌 부모 컴포넌트 (Parent.vue)
<template>
  <ChildComponent @customEvent="handleEvent" />
</template>

<script setup>
import ChildComponent from "./ChildComponent.vue";

const handleEvent = (data) => {
  console.log("부모가 받은 데이터:", data);
};
</script>

➡️ 자식에서 emit("customEvent", 데이터)을 실행하면, 부모는 @customEvent로 데이터를 받을 수 있음.


3️⃣ defineExpose vs defineEmits 정리

기능defineExposedefineEmits
방향자식 → 부모부모 → 자식
역할자식의 특정 메서드/데이터를 부모가 직접 접근할 수 있도록 함부모에게 이벤트를 전달하여 특정 동작을 실행하게 함
사용 방식ref를 통해 부모에서 직접 호출emit()을 통해 부모에게 알림
사용 예시childRef.value.someMethod()emit("event-name", data)

🎯 언제 defineExpose vs defineEmits를 사용할까?

부모가 자식의 특정 메서드를 직접 호출해야 한다면defineExpose

childRef.value.sayHello();

자식이 부모에게 데이터를 전달해야 한다면defineEmits

emit("customEvent", data);

👉 이벤트는 특정 상황에서 실행되며(defineEmits), 함수는 직접 실행하는 코드 블록(defineExpose를 활용하여 호출 가능)

이제 Vue 3에서 이벤트와 함수의 차이를 이해하고, defineExposedefineEmits를 언제 사용해야 하는지 확실히 알았을 거다!

profile
주니어 프론트엔드개발자

0개의 댓글