[컴포넌트 심화-5] 텔레포트, 동적 컴포넌트 &비동기 컴포넌트

2025. 3. 28. 16:51·Frontend/Vue 3
728x90

동적 컴포넌트  (Dynamic Components)

`<component>` 태그와 `is` 속성을 사용해 동적으로 컴포넌트를 변경할 수 있는 기능 제공

즉, 컴포넌트를 고정적으로 렌더링하는 것이 아니라, 상황에 따라 변경 가능

기본 문법

<component :is="currentComponent"></component>

 

  • `:is` 속성에는 렌더링할 컴포넌트의 이름을 전달
  • `currentComponent` 값이 변경되면 자동으로 새로운 컴포넌트로 교체

예제

`ComponentA`와 `ComponentB`를 동적으로 변경하는 예제

<template>
  <div>
    <button @click="toggleComponent">컴포넌트 변경</button>
    <component :is="currentComponent"></component>
  </div>
</template>

<script>
import ComponentA from './ComponentA.vue';
import ComponentB from './ComponentB.vue';

export default {
  data() {
    return {
      currentComponent: 'ComponentA'
    };
  },
  methods: {
    toggleComponent() {
      this.currentComponent = this.currentComponent === 'ComponentA' ? 'ComponentB' : 'ComponentA';
    }
  },
  components: {
    ComponentA,
    ComponentB
  }
};
</script>

 

keep-alive로 상태 유지

동적 컴포넌트를 변경할 경우, 기존 컴포넌트의 상태가 초기화 됨

👉 A에서 이름을 입력 중 B로 이동시, 다시 A로 돌아왔을 때 작성한 이름이 초기화 돼 있음

<keep-alive>
  <component :is="currentComponent"></component>
</keep-alive>

위처럼 `<keep-alive>`를 사용해서 한 번 로드된 컴포넌트의 상태를 유지하면 이름이 초기화 되지 않고 남아 있음


비동기 컴포넌트 (Async Components)

필요할 때만 컴포넌트를 로드하여 성능을 최적화하는 방식

 

  • `defineAsyncComponent`를 사용하여 컴포넌트를 비동기 로딩
  • 코드 스플리팅(Code Splitting)을 통해 초기 번들 크기를 줄이고 로딩 속도를 개선
  • SPA(싱글 페이지 애플리케이션)에서 초기 로딩 속도를 빠르게 하기 위해 사용
<template>
  <component :is="currentComponent"></component>
</template>

<script>
import { defineAsyncComponent, ref } from 'vue';

export default {
  setup() {
    const currentComponent = ref(null);

    // 비동기 로딩
    currentComponent.value = defineAsyncComponent(() =>
      import('./HeavyComponent.vue')
    );

    return { currentComponent };
  }
};
</script>

 

  1. import()를 사용하여 필요할 때만 해당 컴포넌트를 로드
  2. 초기 번들 크기가 줄어들어 앱의 성능이 개선됨.

동적 컴포넌트 vs 비동기 컴포넌트

구분 동적 컴포넌트 비동기 컴포넌트
목적 여러 개의 컴포넌트 중 선택하여 렌더링 필요할 때만 로드하여 성능 최적화
사용법 `<component is="xxxx"> `defineAsyncComponent()`
초기 로딩 속도  느려질 수 있음
∵ 모든 컴포넌트를 로드
빠름
∵ 필요할 때만 로드
예제 탭, UI, 폼 전환 등 대용량 컴포넌트, 코드 스플리팅

 

언제 사용해야 할까?

✅ 동적 컴포넌트가 적합한 경우

  • 여러 개의 UI(탭, 모달 등)를 빠르게 전환해야 하는 경우
  • 같은 페이지 내에서 다른 UI를 동적으로 바꿔야 하는 경우

✅ 비동기 컴포넌트가 적합한 경우

  • 초기 로딩 속도를 최적화하고 싶은 경우
  • 사용자가 접근할 가능성이 낮은 무거운 컴포넌트를 나중에 로드하고 싶은 경우

텔레포트 (Teleport)

컴포넌트의 일부를 DOM 트리의 다른 위치로 이동시킬 수 있는 기능

주로 모달, 툴팁, 드롭다운 등의 컴포넌트를 부모 컴포넌트의 DOM 트리 밖에 렌더링하고자 할 때 유용

<template>
  <div>
    <h1>Main content</h1>
    <!-- Teleport로 이동할 컴포넌트 -->
    <teleport to="body">
      <div class="modal">
        <p>This modal is rendered outside the app's root element!</p>
      </div>
    </teleport>
  </div>
</template>

<script>
export default {
  name: "App",
};
</script>

<style>
.modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: rgba(0, 0, 0, 0.8);
  color: white;
  padding: 20px;
  border-radius: 5px;
}
</style>

 

주요 속성

`to`: 텔레포트된 컴포넌트를 삽입할 대상 DOM 요소를 지정

to는 문자열로 CSS 선택자를 받을 수 있음
예를 들어, `to="body"`는 텔레포트된 내용을 body 태그 안에 렌더링합니다.

동작 원리

Teleport는 기본적으로 Vue 컴포넌트의 자식 DOM 트리에 해당하는 부분을 부모 컴포넌트의 렌더링 트리에서 분리하고, 다른 DOM 위치에 렌더링

이로 인해 부모 컴포넌트와의 관계에서 UI 요소가 격리될 수 있습니다.

주요 활용 예시

  • 모달 창: 모달 창이나 팝업이 부모 컴포넌트의 영역을 벗어나 화면에 띄워져야 할 때.
  • 툴팁: 툴팁이 부모 컴포넌트의 레이아웃에 영향을 받지 않도록.
  • 드롭다운: 드롭다운 메뉴가 다른 UI 요소에 의해 가려지지 않도록.
728x90
'Frontend/Vue 3' 카테고리의 다른 글
  • [단일 파일 컴포넌트-1] 프로젝트 설정
  • Composition API
  • [컴포넌트 심화-4] Provide & Inject
  • [컴포넌트 심화-3] 컴포넌트에서의 v-model 디렉티브
0woy
0woy
Algorithm, CS, Web 등 배운 내용을 기록합니다.
  • 0woy
    0woy dev
    0woy
  • 전체
    오늘
    어제
    • 분류 전체보기 (46) N
      • Backend (4)
        • JAVA (3)
        • DB (1)
      • Frontend (15)
        • HTML5 (1)
        • CSS (1)
        • JS (4)
        • Vue 3 (9)
      • Computer Science (15) N
        • 네트워크 (9) N
        • 운영체제 (5)
      • PS (8)
        • LeetCode (2)
        • Baekjoon (1)
        • Programmers (0)
        • 알고리즘 (5)
      • Dev Trivia (4)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    트리
    list
    DNS
    암시적그래프
    https
    그래프
    BFS
    Props
    select
    map
    implicit graph
    Vue3
    DP
    dom
    java
    udp
    함수
    dfs
    l7 스위치
    JS
    leetcode
    html
    fastretransmit
    상속
    HTTP
    javascript
    속성
    tcp
    set
    function
  • 최근 댓글

  • 최근 글

  • 250x250
  • hELLO· Designed By정상우.v4.10.3
0woy
[컴포넌트 심화-5] 텔레포트, 동적 컴포넌트 &비동기 컴포넌트
상단으로

티스토리툴바