본문 바로가기
프레임워크/Vue, Nuxt

vue.js - Missing required prop (feat. components 와 component)

by 데브조이 2025. 4. 19.
반응형
✔︎ 회사 코드를 그대로 유출할 수 없기 때문에, 작성한 코드는 다른 예제로 변환하여 작성하였다. 

 

개요

회사에서 담당하고 있는 프로젝트의 프론트엔드는 Vue.js 로 구현되어 있다.
오늘은 개발 중 마주한 Missing required prop과 라우터 매핑에서 components와 component의 차이에 대해 다뤄보고자 한다.  


개발 환경

  • Vue 2.7
  • Javascript

상세 에러

main.js:46 [Vue warn]: Missing required prop: "id"

새로운 작성한 컴포넌트를 라우터에 등록하고, props를 정의하니 위와 같은 에러가 콘솔에 나타났다. 
컴포넌트와 라우트에 아래와 같이 props를 제대로 정의했음에도 위 에러를 마주하게 되었다. 

말 그대로 라우팅 시 prop으로 id 값이 전달되어야 하는데, 전달할 값이 없어서 발생한 오류이다.


상황

  • routes/apple.js
// ...
    {
      path: "apples/:id",
      name: "show-apple",
      components: { default: ShowApple },
      props: true,
    },
    
// ...

 

  • ShowApple.vue
// script 블럭 
// ...
    props: {
        id: {
            type: Number,
            required: true
        }
    },
// ...

위와 같이 route와 컴포넌트 props에 id를 지정해 줬는데, id를 인식하지 못하는 문제가 발생했다.

디버깅을 위해 ShowApple.vue 에서 mounted()에 console.log(this.id)를 찍어보니 undefined으로 나왔다.
컴포넌트로 id 자체가 전달이 안 되는 것인지 확인해 보기 위해 this.$route.params.id를 찍어보니 정상적으로 값이 출력되었다. 
이 부분에서 라우터의 props 설정 문제일 수 있음을 파악하였다.

console.log(this.id) // undefined
console.log(this.$route.params.id) // 정상 출력

해결 방법

  • routes/apple.js

 

// ...
    {
      path: "apples/:id",
      name: "show-apple",
      component: ShowApple, // 기존 코드: components: { default: ShowApple }
      props: true,
    },
    
// ...

라우터 정의 시  components 가 아닌 component를 사용하도록 변경하였더니 정상 작동하였다. 
components와 component의 차이가 뭐길래 이런 현상이 발생하는 것일까?


components vs component

일단 이름에서도 알 수 있듯이 두 방식의 차이는 특정 라우터에 매핑할 컴포넌트가 여러 개인지, 단일 컴포넌트인지이다.

 

1. components  - 다중 뷰

이 방식을 이용하면 여러 개의 뷰를 등록할 수 있고, default로 기본 컴포넌트를 등록한다.
이때, props: true 설정을 해도 default 컴포넌트로 props 전달이 안될 수 있다.
만약 해당 방식을 사용해야 한다면, props도 default를 설정해줘야 한다.
예시는 아래와 같다.

{
  path: "apples/:id",
  name: "show-apple",
  components: { default: ShowApple },
  props: { default: route => ({ id: route.params.id }) } 
}

 

2. component  - 단일 뷰

단일 뷰를 등록할 때 사용하는 방식이다.
props: true를 설정하면 컴포넌트로 자동 전달해 준다.


마치며

두 방식 모두 사용할 수 있지만, 단일 컴포넌트라면 component와 props:true를 사용하는 것이 안전한 것 같다. 
앞으로는 두 옵션의 목적에 맞게 사용해야겠다.

반응형