Vue.js 를 배워보자
Vue 3 <script setup>과 TypeScript로 부모-자식 컴포넌트 간 함수 호출 구현 (공통 타입 분리)
_Blue_Sky_
2025. 4. 25. 23:41
728x90

Vue 3의 <script setup> 문법은 Composition API를 간결하게 사용할 수 있게 하며, TypeScript와 함께 사용하면 타입 안전성을 확보할 수 있습니다. 이 글에서는 부모 컴포넌트에서 버튼 클릭 시 부모의 구조체 데이터를 자식 컴포넌트의 함수로 전달해 호출하는 방법을 설명합니다. 특히, TypeScript 인터페이스를 공통 파일로 분리해 부모와 자식 컴포넌트에서 재사용하는 방식에 중점을 둡니다.
목표
-
부모 컴포넌트에서 버튼 클릭 시 구조체 데이터를 자식 컴포넌트로 전달.
-
자식 컴포넌트에서 데이터를 받아 함수로 처리.
-
TypeScript 인터페이스를 공통 파일로 분리해 재사용.
-
<script setup> 문법으로 간결한 코드 작성.
1. 프로젝트 설정
Vue 3 프로젝트에 TypeScript가 설정되어 있다고 가정합니다. Vite로 생성된 프로젝트라면 tsconfig.json과 vue-tsc가 포함되어 있습니다. 필요한 패키지 설치 명령어는 다음과 같습니다:
bash
npm install vue@3 typescript vue-tsc
2. 공통 타입 파일 생성
DataStructure 인터페이스를 공통 파일로 분리해 부모와 자식 컴포넌트에서 재사용합니다. 프로젝트의 src/types 폴더에 타입 파일을 생성합니다.
src/types/DataStructure.ts
export interface DataStructure {
id: number;
name: string;
value: number;
}
설명:
-
DataStructure 인터페이스를 정의해 구조체의 타입을 명시합니다.
-
export로 외부에서 사용할 수 있도록 노출합니다.
-
src/types 폴더는 타입 정의를 중앙화해 관리하기에 적합합니다.
728x90
3. 자식 컴포넌트 구현
자식 컴포넌트(ChildComponent.vue)는 공통 타입을 임포트해 부모로부터 받은 데이터를 처리하는 함수를 정의합니다.
src/components/ChildComponent.vue
<template>
<div>
<h3>자식 컴포넌트</h3>
<p>받은 데이터: {{ displayData }}</p>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { DataStructure } from '../types/DataStructure';
// 데이터 표시용 ref
const displayData = ref<string>('');
// 부모가 호출할 함수
const processData = (data: DataStructure) => {
displayData.value = `ID: ${data.id}, Name: ${data.name}, Value: ${data.value}`;
console.log('자식 컴포넌트에서 데이터 처리:', data);
};
// 부모 컴포넌트에서 접근할 수 있도록 함수 노출
defineExpose({
processData,
});
</script>
설명:
-
DataStructure를 ../types/DataStructure에서 임포트합니다.
-
processData 함수는 DataStructure 타입의 데이터를 받아 처리합니다.
-
defineExpose로 processData를 부모 컴포넌트에서 접근 가능하도록 노출합니다.
-
<script setup>을 사용해 간결하게 작성합니다.
728x90
4. 부모 컴포넌트 구현
부모 컴포넌트(ParentComponent.vue)는 버튼 클릭 시 자식 컴포넌트의 processData 함수를 호출하고, 공통 타입을 사용해 구조체 데이터를 전달합니다.
src/components/ParentComponent.vue
vue
<template>
<div>
<h1>부모 컴포넌트</h1>
<button @click="handleButtonClick">자식 함수 호출</button>
<ChildComponent ref="childRef" />
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
import { DataStructure } from '../types/DataStructure';
// 자식 컴포넌트의 참조
const childRef = ref<InstanceType<typeof ChildComponent> | null>(null);
// 부모의 구조체 데이터
const parentData: DataStructure = {
id: 1,
name: '샘플 데이터',
value: 100,
};
// 버튼 클릭 핸들러
const handleButtonClick = () => {
if (childRef.value) {
// 자식 컴포넌트의 processData 함수 호출
childRef.value.processData(parentData);
}
};
</script>
설명:
-
DataStructure를 ../types/DataStructure에서 임포트합니다.
-
parentData는 DataStructure 타입으로 정의됩니다.
-
ref로 자식 컴포넌트를 참조하며, InstanceType으로 타입을 명시합니다.
-
handleButtonClick은 자식 컴포넌트의 processData 함수를 호출합니다.
5. 동작 원리
-
부모 컴포넌트에서 버튼을 클릭하면 handleButtonClick이 실행됩니다.
-
childRef를 통해 자식 컴포넌트의 processData 함수를 호출하고 parentData를 전달합니다.
-
자식 컴포넌트는 데이터를 처리해 템플릿에 결과를 표시합니다.
6. 공통 타입 분리의 장점
-
재사용성: DataStructure를 여러 컴포넌트에서 동일하게 사용해 일관성을 유지합니다.
-
유지보수 용이: 타입 정의를 한 곳에서 관리하므로 수정이 간편합니다.
-
타입 안전성: TypeScript의 타입 검사를 통해 데이터 구조의 오류를 사전에 방지합니다.
7. 주의사항
-
타입 파일 경로: src/types 폴더를 사용했지만, 프로젝트 구조에 따라 경로를 조정하세요.
-
defineExpose: <script setup>에서는 defineExpose로 명시적으로 함수를 노출해야 부모가 접근할 수 있습니다.
-
Ref 체크: childRef.value가 null일 수 있으므로 안전하게 접근하세요.
-
Props 대안: 함수 호출 대신 단순 데이터 전달이 필요하다면 props를 사용하는 것도 고려하세요.
8. 실행 결과
부모 컴포넌트에서 버튼을 클릭하면 자식 컴포넌트에 다음이 표시됩니다:
받은 데이터: ID: 1, Name: 샘플 데이터, Value: 100
콘솔에는 자식 컴포넌트에서 데이터 처리: { id: 1, name: '샘플 데이터', value: 100 }이 출력됩니다.
9. 추가 팁
-
타입 중앙화: 프로젝트가 커질수록 types 폴더에 더 많은 타입을 추가해 관리하세요.
-
이벤트 기반 설계: 자식에서 emit을 사용해 부모로 이벤트를 전달하는 방식도 유용할 수 있습니다.
-
Volar 확장: VSCode에서 Vue와 TypeScript를 사용할 때는 Volar 확장을 설치해 타입 검사와 자동 완성을 강화하세요.
728x90