We use cookies to enhance your experience on the site
CodeWorlds

Transition Between Routes

At NOVA LAB, transitioning between station sections — from the command center to the laboratory, from the reactor to the hangar — should be smooth and natural. Vue Router supports transition animations between pages thanks to its integration with the

<Transition>
component.

RouterView + Transition

To animate router view changes, you use the slot API on

<RouterView>
. Vue Router provides the current component as a slot variable:

1<RouterView v-slot="{ Component }">
2  <Transition name="page" mode="out-in">
3    <component :is="Component" />
4  </Transition>
5</RouterView>

Here's how it works step by step:

  1. <RouterView v-slot="{ Component }">
    — the router provides the current page component as
    Component
  2. <Transition name="page" mode="out-in">
    — you wrap the dynamic component in a Transition
  3. <component :is="Component" />
    — you render the dynamic page component

Three key rules:

  • Use
    v-slot="{ Component }"
    — you cannot directly wrap
    <RouterView>
    in
    <Transition>
    (this won't work in Vue 3)
  • Always add
    mode="out-in"
    — without it, the old and new pages will animate simultaneously, which looks chaotic
  • Don't add
    :key
    on
    <component>
    — Vue Router automatically reacts to route changes

The corresponding CSS classes:

1.page-enter-active,
2.page-leave-active {
3  transition: all 0.3s ease;
4}
5
6.page-enter-from {
7  opacity: 0;
8  transform: translateX(20px);
9}
10
11.page-leave-to {
12  opacity: 0;
13  transform: translateX(-20px);
14}

Per-Route Transitions

Each section of the NOVA LAB station can have a different animation type — the command center slides in from the left, the alerts panel pops up from below. Use the

meta
field in the route definition to assign an animation name:

1const routes = [
2  {
3    path: '/dashboard',
4    component: Dashboard,
5    meta: { transition: 'slide-left' }
6  },
7  {
8    path: '/settings',
9    component: Settings,
10    meta: { transition: 'slide-right' }
11  },
12  {
13    path: '/alerts',
14    component: Alerts,
15    meta: { transition: 'slide-up' }
16  }
17]

In the template, read the animation name from the

route
object:

1<RouterView v-slot="{ Component, route }">
2  <Transition :name="route.meta.transition || 'fade'" mode="out-in">
3    <component :is="Component" />
4  </Transition>
5</RouterView>

Note the

|| 'fade'
— this is a fallback for routes without a defined animation. The
v-slot
gives you access to both
Component
(the current page component) and
route
(the route object with meta data).

Dynamic Animations Based on Navigation Direction

You can change the animation depending on whether the user is navigating "forward" or "backward":

1<script setup>
2import { ref } from 'vue'
3import { useRouter } from 'vue-router'
4
5const transitionName = ref('slide-left')
6const router = useRouter()
7
8router.beforeEach((to, from) => {
9  // Compare page depths to determine direction
10  const toDepth = to.path.split('/').length
11  const fromDepth = from.path.split('/').length
12
13  transitionName.value = toDepth < fromDepth ? 'slide-right' : 'slide-left'
14})
15</script>
16
17<template>
18  <RouterView v-slot="{ Component }">
19    <Transition :name="transitionName" mode="out-in">
20      <component :is="Component" />
21    </Transition>
22  </RouterView>
23</template>

With KeepAlive

You can combine Transition with KeepAlive to cache page views. This is useful when the user frequently switches between the same station sections and you don't want to lose state (e.g., scroll position, entered data):

1<RouterView v-slot="{ Component }">
2  <Transition name="fade" mode="out-in">
3    <KeepAlive :max="5">
4      <component :is="Component" />
5    </KeepAlive>
6  </Transition>
7</RouterView>

The order matters —

<Transition>
on the outside,
<KeepAlive>
on the inside. The
:max="5"
attribute limits the number of cached components to avoid excessive memory usage.

Practical Notes

  • Page transition animations should be short (200-400ms) — the user wants to see the content quickly
  • Avoid heavy animations (e.g., 3D transforms) on mobile devices
  • Test animations on slower devices — an effect that looks great on a fast computer may lag on a tablet
  • Prefer
    opacity
    and
    transform
    — these properties are GPU-accelerated
Go to CodeWorlds