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.jsonvue-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 타입의 데이터를 받아 처리합니다.
  • defineExposeprocessData를 부모 컴포넌트에서 접근 가능하도록 노출합니다.
  • <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에서 임포트합니다.
  • parentDataDataStructure 타입으로 정의됩니다.
  • ref로 자식 컴포넌트를 참조하며, InstanceType으로 타입을 명시합니다.
  • handleButtonClick은 자식 컴포넌트의 processData 함수를 호출합니다.
5. 동작 원리
  1. 부모 컴포넌트에서 버튼을 클릭하면 handleButtonClick이 실행됩니다.
  2. childRef를 통해 자식 컴포넌트의 processData 함수를 호출하고 parentData를 전달합니다.
  3. 자식 컴포넌트는 데이터를 처리해 템플릿에 결과를 표시합니다.
6. 공통 타입 분리의 장점
  • 재사용성: DataStructure를 여러 컴포넌트에서 동일하게 사용해 일관성을 유지합니다.
  • 유지보수 용이: 타입 정의를 한 곳에서 관리하므로 수정이 간편합니다.
  • 타입 안전성: TypeScript의 타입 검사를 통해 데이터 구조의 오류를 사전에 방지합니다.
7. 주의사항
  • 타입 파일 경로: src/types 폴더를 사용했지만, 프로젝트 구조에 따라 경로를 조정하세요.
  • defineExpose: <script setup>에서는 defineExpose로 명시적으로 함수를 노출해야 부모가 접근할 수 있습니다.
  • Ref 체크: childRef.valuenull일 수 있으므로 안전하게 접근하세요.
  • Props 대안: 함수 호출 대신 단순 데이터 전달이 필요하다면 props를 사용하는 것도 고려하세요.
8. 실행 결과
부모 컴포넌트에서 버튼을 클릭하면 자식 컴포넌트에 다음이 표시됩니다:
 
받은 데이터: ID: 1, Name: 샘플 데이터, Value: 100
콘솔에는 자식 컴포넌트에서 데이터 처리: { id: 1, name: '샘플 데이터', value: 100 }이 출력됩니다.
9. 추가 팁
  • 타입 중앙화: 프로젝트가 커질수록 types 폴더에 더 많은 타입을 추가해 관리하세요.
  • 이벤트 기반 설계: 자식에서 emit을 사용해 부모로 이벤트를 전달하는 방식도 유용할 수 있습니다.
  • Volar 확장: VSCode에서 Vue와 TypeScript를 사용할 때는 Volar 확장을 설치해 타입 검사와 자동 완성을 강화하세요.

 
728x90