Transitions
In order to use transitions on your route components and animate navigations, you need to use the v-slot API:
<router-view v-slot="{ Component }">
<transition name="fade">
<component :is="Component" />
</transition>
</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>
:
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 }">
<!-- Use any custom transition and fallback to `fade` -->
<transition :name="route.meta.transition || 'fade'">
<component :is="Component" />
</transition>
</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:
<!-- use a dynamic transition name -->
<router-view v-slot="{ Component, route }">
<transition :name="route.meta.transitionName">
<component :is="Component" />
</transition>
</router-view>
We can add an after navigation hook to dynamically add information to the meta
field based on the depth of the route
router.afterEach((to, from) => {
const toDepth = to.path.split('/').length
const fromDepth = from.path.split('/').length
to.meta.transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left'
})
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:
<router-view v-slot="{ Component, route }">
<transition name="fade">
<component :is="Component" :key="route.path" />
</transition>
</router-view>