이번 포스트에서는 동적 컴포넌트(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>