번역 자료 / / 2025. 7. 17. 16:44

[vue 번역] 컴포넌트 기초 (Component Basics)

출처: https://vuejs.org/guide/essentials/component-basics.html

컴포넌트를 사용하면 UI를 독립적이고 재사용 가능한 부분으로 분할하고 각 부분을 개별적으로 생각할 수 있습니다. 컴포넌트는 중첩될 수 있으며, 일반적으로 애플리케이션은 컴포넌트 트리로 구성됩니다.

App
├─ TodoList
│  ├─ TodoItem
│  │  ├─ TodoDeleteButton
│  │  └─ TodoEditButton
│  └─ TodoAddForm
└─ Conversation
   ├─ MessageList
   │  └─ MessageItem
   └─ MessageAddForm

컴포넌트 정의하기 (Defining a Component)

빌드 단계를 사용할 때, 일반적으로 각 Vue 컴포넌트를 전용 파일(예: .vue 파일)에 정의합니다. 이를 단일 파일 컴포넌트(Single-File Component, SFC)라고 합니다.

<script setup>
import { ref } from 'vue'

const count = ref(0)
</script>

<template>
  <button @click="count++">You clicked me {{ count }} times.</button>
</template>

<style scoped>
button {
  font-weight: bold;
}
</style>

컴포넌트 사용하기 (Using a Component)

자식 컴포넌트를 사용하려면 부모 컴포넌트에서 가져와야 합니다. ButtonCounter.vueApp.vue와 동일한 디렉토리에 있다고 가정하면, 다음과 같이 가져올 수 있습니다.

<script setup>
import ButtonCounter from './ButtonCounter.vue'
</script>

<template>
  <h1>Here are many child components!</h1>
  <ButtonCounter />
  <ButtonCounter />
  <ButtonCounter />
</template>

<script setup>을 사용하면 가져온 컴포넌트를 템플릿에서 직접 사용할 수 있습니다. 컴포넌트는 태그처럼 사용할 수 있습니다. 모든 컴포넌트는 여러 번 재사용할 수 있습니다.

Props 전달하기 (Passing Props)

컴포넌트는 재사용을 위해 만들어졌습니다. 부모에서 자식으로 데이터를 전달해야 할 가능성이 높습니다. 이를 위해 props를 사용합니다.

Props는 컴포넌트에 등록할 수 있는 사용자 정의 속성입니다. 값이 prop 속성에 전달되면 해당 컴포넌트 인스턴스의 속성이 됩니다. ButtonCounter 컴포넌트가 부모로부터 title prop을 받도록 하려면 defineProps 매크로를 사용해야 합니다.

// ButtonCounter.vue
<script setup>
import { ref } from 'vue'

defineProps(['title'])

const count = ref(0)
</script>

<template>
  <h4>{{ title }}</h4>
  <button @click="count++">You clicked me {{ count }} times.</button>
</template>

이제 부모 컴포넌트에서 이 title을 전달할 수 있습니다.

<script setup>
import ButtonCounter from './ButtonCounter.vue'
</script>

<template>
  <h1>Here are many child components!</h1>
  <ButtonCounter title="Give me a title" />
  <ButtonCounter title="Give me another title" />
</template>

이벤트 수신하기 (Listening to Events)

자식 컴포넌트가 개발됨에 따라 부모 컴포넌트와 다시 통신해야 할 수도 있습니다. 예를 들어, <ButtonCounter> 컴포넌트가 클릭될 때마다 부모에게 알리고 싶을 수 있습니다.

이 솔루션은 Vue의 사용자 정의 이벤트 시스템입니다. 부모는 v-on 또는 @를 사용하여 자식 컴포넌트의 모든 이벤트를 수신하도록 선택할 수 있습니다. 마치 네이티브 DOM 이벤트와 같습니다.

자식 컴포넌트는 내장된 $emit 메서드를 사용하여 템플릿 표현식(예: v-on 핸들러)에서 직접 사용자 정의 이벤트를 발생시킬 수 있습니다.

// ButtonCounter.vue
<script setup>
import { ref } from 'vue'

defineProps(['title'])
const emit = defineEmits(['enlarge-text'])

const count = ref(0)
</script>

<template>
  <h4>{{ title }}</h4>
  <button @click="count++">You clicked me {{ count }} times.</button>
  <button @click="emit('enlarge-text')">Enlarge text</button>
</template>

부모는 이제 enlarge-text 이벤트를 수신하고 부모의 데이터를 업데이트할 수 있습니다.

<script setup>
import { ref } from 'vue'
import ButtonCounter from './ButtonCounter.vue'

const postFontSize = ref(1)
</script>

<template>
  <div :style="{ fontSize: postFontSize + 'em' }">
    <ButtonCounter
      title="Give me a title"
      @enlarge-text="postFontSize += 0.1"
    />
    <ButtonCounter
      title="Give me another title"
      @enlarge-text="postFontSize += 0.1"
    />
  </div>
</template>

슬롯을 이용한 콘텐츠 배포 (Content Distribution with Slots)

HTML 엘리먼트와 마찬가지로, 컴포넌트에 콘텐츠를 전달할 수 있는 것이 유용할 때가 많습니다. 예를 들면 다음과 같습니다.

<AlertBox>
  Something bad happened.
</AlertBox>

이는 Vue의 <slot> 엘리먼트로 달성할 수 있습니다.

<!-- AlertBox.vue -->
<template>
  <div class="alert-box">
    <strong>This is an Error for Demo Purposes</strong>
    <slot />
  </div>
</template>

<style scoped>
.alert-box {
  /* ... */
}
</style>

<slot> 엘리먼트는 부모가 전달한 슬롯 콘텐츠의 플레이스홀더 역할을 합니다. 슬롯 콘텐츠는 정적일 수도 있고, 반응형 데이터를 사용하여 동적일 수도 있습니다.

동적 컴포넌트 (Dynamic Components)

탭 인터페이스처럼 컴포넌트 간에 동적으로 전환하는 것이 유용할 때가 있습니다. 이는 Vue의 <component> 엘리먼트와 특별한 is 속성을 사용하여 가능합니다.

<script setup>
import { ref } from 'vue'
import Home from './Home.vue'
import Posts from './Posts.vue'
import Archive from './Archive.vue'

const currentTab = ref('Home')

const tabs = {
  Home,
  Posts,
  Archive
}
</script>

<template>
  <div class="demo">
    <button
      v-for="(_, tab) in tabs"
      :key="tab"
      :class="['tab-button', { active: currentTab === tab }]"
      @click="currentTab = tab"
    >
      {{ tab }}
    </button>
    <component :is="tabs[currentTab]" class="tab"></component>
  </div>
</template>

is에 전달된 값은 컴포넌트의 이름 문자열이거나 실제 컴포넌트 객체일 수 있습니다.

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유