Transitions

Watch a free video lesson on Vue School

In order to use transitions on your route components and animate navigations, you need to use the v-slot API:

  1. <router-view v-slot="{ Component }">
  2. <transition name="fade">
  3. <component :is="Component" />
  4. </transition>
  5. </router-view>

All transition APIs work the same here.

Per-Route Transition

The above usage will apply the same transition for all routes. If you want each route’s component to have different transitions, you can instead combine meta fields and a dynamic name on <transition>:

  1. const routes = [
  2. {
  3. path: '/custom-transition',
  4. component: PanelLeft,
  5. meta: { transition: 'slide-left' },
  6. },
  7. {
  8. path: '/other-transition',
  9. component: PanelRight,
  10. meta: { transition: 'slide-right' },
  11. },
  12. ]
  1. <router-view v-slot="{ Component, route }">
  2. <!-- Use any custom transition and fallback to `fade` -->
  3. <transition :name="route.meta.transition || 'fade'">
  4. <component :is="Component" />
  5. </transition>
  6. </router-view>

Route-Based Dynamic Transition

It is also possible to determine the transition to use dynamically based on the relationship between the target route and current route. Using a very similar snippet to the one just before:

  1. <!-- use a dynamic transition name -->
  2. <router-view v-slot="{ Component, route }">
  3. <transition :name="route.meta.transitionName">
  4. <component :is="Component" />
  5. </transition>
  6. </router-view>

We can add an after navigation hook to dynamically add information to the meta field based on the depth of the route

  1. router.afterEach((to, from) => {
  2. const toDepth = to.path.split('/').length
  3. const fromDepth = from.path.split('/').length
  4. to.meta.transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left'
  5. })

Forcing a transition between reused views

Vue might automatically reuse components that look alike, avoiding any transition. Fortunately, it is possible to add a key attribute to force transitions. This also allows you to trigger transitions while staying on the same route with different params:

  1. <router-view v-slot="{ Component, route }">
  2. <transition name="fade">
  3. <component :is="Component" :key="route.path" />
  4. </transition>
  5. </router-view>