Search

[Vue3] Props 정리

props 는 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달하는 방식을 말한다.
TheView.vue 라는 부모 컴포넌트에서 각각의 AppCard.vue 라는 자식 컴포넌트로 데이터를 전달하는 상황을 가정해보자
props 를 전달하는 방식은 여러가지가 있다.

부모 컴포넌트 ( TheView.vue )

1. 정적 데이터 전달

<script setup> import AppCard from '@/components/AppCard.vue'; </script>
HTML
복사
<AppCard title="제목1" content="내용1"></AppCard>
HTML
복사
<AppCard> 컴포넌트에 title="제목1content="내용1" 을 직접 전달한다.

2. 동적 데이터 전달

<script setup> import AppCard from '@/components/AppCard.vue'; import { reactive } from 'vue'; const post = reactive({ title: '제목2', content: '내용2', }); </script>
HTML
복사
<AppCard :title="post.title" :content="post.content"></AppCard>
HTML
복사
이런식으로 : (콜론)을 사용하여 데이터 바인딩(v-bind:)을 적용해서 post 객체의 값을 props 로 전달할 수도 있다.
만약 <AppCard> 컴포넌트가 여러 개일 경우 v-for 디렉티브를 통해 아래와 같이 표현 할 수도 있다.
<div v-for="(post, index) in posts" :key="index"> <AppCard :title="post.title" :content="post.content" ></AppCard> </div>
HTML
복사

자식 컴포넌트 ( AppCard.vue )

TheView.vue 에서 전달 받은 props 를 자식 컴포넌트에서 표현할 때는 아래와 같이 표현 가능하다.
<template> <div> <h5>{{ title }}</h5> <p>{{ content }}</p> </div> </template>
HTML
복사
Vue 컴포넌트는 외부에서 컴포넌트로 props 를 넘길 때 어떤 속성이 처리 되어야 하는지 알기 위해 명시적인 props 선언을 아래와 같이 요구한다.
// <script setup>에서는 defineProps()를 통해 props 선언이 가능하다. defineProps({ title: { type: String, required: true }, content: { type: String, required: true } });
JavaScript
복사

1. 컴포넌트 속성 정의

props 를 정의할 때 사용할 수 있는 속성들은 아래와 같다.
1.
type (데이터 타입 지정)
defineProps({ title: String, // 단일 타입 (문자열만 허용) count: Number, // 숫자만 허용 isActive: Boolean, // true 또는 false data: Object, // 객체 타입 items: Array, // 배열 타입 callback: Function, // 함수 타입 mixed: [String, Number] // 문자열 또는 숫자 허용 (여러 타입 가능) });
JavaScript
복사
2.
required (필수 여부)
defineProps({ title: { type: String, required: true } // 반드시 전달해야 함 });
JavaScript
복사
<!-- title을 전달하지 않은 경우 Missing required prop: "title" 경고 발생 --> <AppCard />
HTML
복사
3.
default (기본값 설정)
// 부모 컴포넌트에서 값을 전달하지 않았을 때의 기본 값을 설정 // type이 Object 또는 Array 일 경우, 함수를 사용하여 기본 값을 반환하여야 한다. defineProps({ type: { type: String, default: 'news' }, // 기본값: 'news' isLike: { type: Boolean, default: false }, // 기본값: false count: { type: Number, default: 0 }, // 기본값: 0 options: { type: Array, default: () => [] // 기본값: 빈 배열 (함수 사용) }, config: { type: Object, default: () => ({ theme: 'light' }) // 기본값: 객체 (함수 사용) } });
JavaScript
복사
4.
validator (유효성 검사)
// props가 특정 조건을 만족하는지 검사 가능 defineProps({ status: { type: String, validator: (value) => ['pending', 'success', 'error'].includes(value) } });
JavaScript
복사
<!-- completed 는 validator에 없으므로 경고 창 출 --> <AppCard status="completed" />
HTML
복사
required , default , validator 속성이 조합된 props 조합 예제
defineProps({ title: { type: String, required: true }, // 필수 값 count: { type: Number, default: 0 }, // 기본값 설정 status: { type: String, default: 'pending', validator: (value) => ['pending', 'success', 'error'].includes(value) // 유효성 검사 } });
JavaScript
복사

단방향 데이터 흐름

모든 props 는 부모 컴포넌트와 자식 컴포넌트 사이에 단방향 바인딩으로 형성되어 있다. 부모에서 속성이 업데이트되면 자식에서 그 값이 반영되지만, 그 반대는 아니다.
이렇게 하면 자식 컴포넌트가 실수로 부모의 상태를 변경하여 앱의 데이터 흐름을 이해하기 어렵게 만드는 것을 방지할 수 있다.

References