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="제목1 과 content="내용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 는 부모 컴포넌트와 자식 컴포넌트 사이에 단방향 바인딩으로 형성되어 있다. 부모에서 속성이 업데이트되면 자식에서 그 값이 반영되지만, 그 반대는 아니다.
이렇게 하면 자식 컴포넌트가 실수로 부모의 상태를 변경하여 앱의 데이터 흐름을 이해하기 어렵게 만드는 것을 방지할 수 있다.