Vue 3.0/04.Component

[vue 3] 07. 동적 컴포넌트

  • -

이번 포스트에서는 동적 컴포넌트(dynamic component)에 대해 살펴보자.

 

동적 컴포넌트

 

동적 컴포넌트 구성

dynamic component는 동적으로 component를 교체해야 하는 경우 사용된다. 대표적인 예로 탭으로 구성된 UI등을 생각해볼 수 있다.  dynamic component를 사용하기 위해서는 <component> 태그의 is라는 속성에 표시할 component를 할당해주면 된다.

is 속성에는 등록된 컴포넌트의 이름 문자열이나 실제 컴포넌트 객체를 등록할 수 있다. 컴포넌트를 등록할 때 주의 사항은 컴포넌트 변수 선언 시 ref 가 아닌 shallowRef를 사용해야 한다는 점이다. 만약에 ref를 사용하면 성능상 overhead가 발생한다는 경고가 console에 출력된다.  shallowRef는 value까지만 반응성을 유지하고 내부 깊숙이까지 반응형으로 동작하지는 않는다.(https://ko.vuejs.org/api/reactivity-advanced.html#shallowref)

[Vue warn]: Vue received a Component which was made a reactive object. This can lead to unnecessary performance overhead, and should be avoided by marking the component with `markRaw` or using `shallowRef` instead of `ref`

 

<script setup>
import CounterVue from './components/dynamic/DynamicCounter.vue'
import MessageVue from './components/dynamic/DynamicMessage.vue'
import { shallowRef } from 'vue'

const current = shallowRef(CounterVue) // ref 대산 shallowRef
const change = (val) => {
  current.value = val == 'counter' ? CounterVue : MessageVue
}

</script>

<template>
  <button @click="change('message')">message</button>
  <button @click="change('counter')">counter</button>
  <component :is="current"></component>
</template>

 

동적 컴포넌트의 상태 유지

일반적으로 동적 컴포넌트가 비활성화 되면 unmounted까지 진행해서 재사용이 불가하다. 만약 이런 상황에서 컴포넌트의 상태를 유지해야 한다면 <KeepAlive>라는 빌트인 컴포넌트로 <component>를 감싸주면 된다.

  <KeepAlive>
    <component :is="current"></component>
  </KeepAlive>

KeepAlive 컴포넌트의 속성으로는 include와 exclude 속성이 있는데 이는 특정 컴포넌트만 상태를 유지하거나 특정 컴포넌트는 유지하고 싶지 않을 경우 사용할  수 있다.

예를 들어 다음은 DynamicCounter를 제외하고는 캐싱한다.

<KeepAlive exclude="DynamicCounter">
    <component :is="current"></component>
</KeepAlive>

 

반대로 다음은 DynamicCounter만 캐싱한다.

<KeepAlive include="DynamicCounter">
    <component :is="current"></component>
</KeepAlive>

참고로 setup에서는 vue 파일의 이름이 컴포넌트의 이름으로 자동 추론된다.

include 내용을 작성할 때는 , 로 여러개를 구분해서 등록할 수 있다. v-bind를 이용하면 정규 표현식이나 배열을 사용할 수도 있다.

<KeepAlive include="a,b"></KeepAlive>
<KeepAlive :include="/a|b/"></KeepAlive>
<KeepAlive :include="['a', 'b']"></KeepAlive>
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.