트랜지션
라우트 컴포넌트에서 트랜지션을 사용하고 내비게이션에 애니메이션을 적용하려면 <RouterView>
슬롯을 사용해야 합니다:
<router-view v-slot="{ Component }">
<transition name="fade">
<component :is="Component" />
</transition>
</router-view>
모든 트랜지션 API는 여기서도 동일하게 동작합니다.
라우트별 트랜지션
위의 사용법은 모든 라우트에 동일한 트랜지션을 적용합니다. 각 라우트의 컴포넌트마다 다른 트랜지션을 적용하고 싶다면, meta 필드와 <transition>
의 동적 name
을 조합할 수 있습니다:
const routes = [
{
path: '/custom-transition',
component: PanelLeft,
meta: { transition: 'slide-left' },
},
{
path: '/other-transition',
component: PanelRight,
meta: { transition: 'slide-right' },
},
]
<router-view v-slot="{ Component, route }">
<!-- 커스텀 트랜지션을 사용하거나 `fade`로 대체 -->
<transition :name="route.meta.transition || 'fade'">
<component :is="Component" />
</transition>
</router-view>
라우트 기반 동적 트랜지션
타겟 라우트와 현재 라우트 간의 관계에 따라 사용할 트랜지션을 동적으로 결정할 수도 있습니다. 바로 앞의 예시와 매우 비슷한 코드를 사용합니다:
<!-- 동적 트랜지션 이름 사용 -->
<router-view v-slot="{ Component, route }">
<transition :name="route.meta.transition">
<component :is="Component" />
</transition>
</router-view>
내비게이션 후크를 추가하여 라우트의 깊이에 따라 meta
필드에 동적으로 정보를 추가할 수 있습니다
router.afterEach((to, from) => {
const toDepth = to.path.split('/').length
const fromDepth = from.path.split('/').length
to.meta.transition = toDepth < fromDepth ? 'slide-right' : 'slide-left'
})
재사용되는 뷰 간 트랜지션 강제 적용
Vue는 비슷해 보이는 컴포넌트를 자동으로 재사용하여 트랜지션을 생략할 수 있습니다. 다행히도, key
속성 추가를 통해 트랜지션을 강제로 적용할 수 있습니다. 이를 통해 동일한 라우트에서 파라미터만 다를 때도 트랜지션을 트리거할 수 있습니다:
<router-view v-slot="{ Component, route }">
<transition name="fade">
<component :is="Component" :key="route.path" />
</transition>
</router-view>
초기 내비게이션과 트랜지션
일반적으로 Vue의 <Transition>
에서는 appear
prop을 추가하지 않으면 enter 애니메이션이 무시됩니다. 하지만 <RouterView>
와 함께 사용할 때는 appear
prop이 설정되지 않아도 트랜지션이 항상 적용되는 것을 알 수 있습니다. 이는 Vue Router에서 내비게이션이 비동기적으로 처리되기 때문으로, Vue 애플리케이션이 초기 내비게이션이 끝나기 전에 한 번 렌더링되기 때문입니다. 이를 적응하는 방법에는 여러 가지가 있습니다. 가장 쉬운 방법은 isReady
를 사용해 초기 내비게이션이 완료된 후 앱을 마운트하는 것입니다:
const app = createApp(App)
app.use(router)
// 초기 내비게이션이 준비된 후 마운트
await router.isReady()
app.mount('#app')