본문 바로가기
프로그래밍

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의 타입 명시도 꼭 활용해보세요!