본문 바로가기
카테고리 없음

Vue3에서 Props와 Emits를 타입으로 명확하게 정의하는 방법

by 유형제맘 2025. 7. 23.

Vue3에서는 Composition API의 도입으로 컴포넌트 구조가 훨씬 유연해졌습니다. 그중에서도 props와 emits의 타입 명시 방식은 Vue2와 비교해 큰 변화 중 하나인데요. 이번 글에서는 Vue3에서 props와 emits를 어떻게 더 명확하고 타입 안전하게 정의할 수 있는지, 그리고 실제 코드 예제를 통해 쉽게 이해할 수 있도록 설명드릴게요.

Vue2에서는 props와 emits를 어떻게 사용했을까?

Vue2에서는 props는 배열 또는 객체 형태로 선언했고, $emit은 별도 선언 없이 자유롭게 호출할 수 있었습니다.

// Vue2 방식
export default {
  props: ['title'],
  methods: {
    send() {
      this.$emit('submit', 'hello')
    }
  }
}

 

Vue3에서는 어떻게 바뀌었을까?

Vue3에서는 props와 emits에 대해 타입을 명시할 수 있게 되었습니다. 특히 <script setup> 구문을 사용할 경우, defineProps, defineEmits를 통해 훨씬 깔끔하고 명확하게 사용할 수 있어요.

defineProps / defineEmits로 타입 명시하기

<script setup lang="ts">
const props = defineProps<{
  title: string
  count?: number
}>()

const emit = defineEmits<{
  (e: 'submit', value: string): void
  (e: 'cancel'): void
}>()

function send() {
  emit('submit', '전송할 데이터')
}
</script>

 

설명

  • defineProps<T>(): 컴포넌트가 받을 props의 타입 정의
  • defineEmits<T>(): 컴포넌트가 발생시킬 이벤트 타입 정의

이렇게 작성하면 타입 추론이 가능하고, IDE(코드 에디터)에서도 자동완성 및 오류 검출이 되기 때문에 개발 속도와 안정성이 크게 향상됩니다.

 

옵션 API 방식도 여전히 사용 가능

Vue2 스타일에 익숙한 분들은 여전히 아래처럼 사용할 수 있습니다.

export default {
  props: {
    title: String,
    count: {
      type: Number,
      default: 0
    }
  },
  emits: ['submit', 'cancel'],
  setup(props, { emit }) {
    emit('submit', 'hello')
  }
}

emits를 객체로 선언하면 유효성 검사도 가능해요.

emits: {
  submit: (value: string) => typeof value === 'string',
  cancel: null // payload가 없는 이벤트
}

타입 명시의 장점은?

  • 코드의 안정성 증가
    - 오타나 잘못된 타입 사용 시 컴파일 단계에서 에러를 알려줌
  • IDE 자동완성 지원
    - 이벤트 이름이나 props를 직접 기억할 필요 없이 추천 목록 제공
  • 협업 및 유지보수 효율 향상
    - 컴포넌트의 입출력이 명확히 드러나 코드 가독성이 높아짐

마무리하며

Vue3에서는 단순히 문법이 달라진 것이 아니라, 타입 기반의 안전한 개발 환경을 지원하기 위해 많은 변화가 있었습니다.
특히 defineProps와 defineEmits는 컴포넌트 개발 시 입출력 인터페이스를 명시적으로 정의할 수 있게 해주며, 이를 통해 개발 실수도 줄이고, 협업도 쉬워집니다. Vue3를 본격적으로 도입하신다면, Composition API와 함께 props/emits의 타입 명시도 꼭 활용해보세요!