Search code examples
javascriptvue.jsvue-transitions

Vue transitions are not working for router-link and $router.push


I've the following App.vue file:

<script setup>
import { RouterView } from "vue-router";
</script>

<template>
  <RouterView v-slot="{ Component }">
    <transition :name="fade" mode="out-in">
      <component :is="Component" />
    </transition>
  </RouterView>
</template>

And the following router file:

import { createRouter, createWebHistory } from "vue-router";

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: "/",
      name: "signin",
      component: () => import("../views/signin.vue"),
    },
    {
      path: "/dashboard",
      name: "dashboard",
      component: () => import("../views/dashboard.vue"),
    },
  ],
});

export default router;

When I run my application and click any link, no transition is happening, no matter if it use $router.push("/dashboard"); or router-link(to="/dashboard" active-class="active"). I've already checked out many other questions and tutorials but unfortunately it's still not working. Any idea why no transition happens?


Solution

  • There are a couple of things that you can change in your code.

    First, you don't need to declare an import for RouterView as it is globally registered. As long as vue-router is installed in your project, you can safely use RouterView or router-view directly on your template.

    Second, you need to change your name prop to a static prop. Writing :name="fade" means you are passing the value of the variable fade to name. Based on your code, I'm assuming fade is not a variable but a string which means you need to change your prop to name="fade". Read more about static and dynamic props.

    Lastly, transitions require the use of CSS. Since you're declaring a named transition, you need to add the following CSS:

    .fade-enter-active,
    .fade-leave-active {
      transition: opacity 0.5s ease;
    }
    
    .fade-enter-from,
    .fade-leave-to {
      opacity: 0;
    }
    

    Notice the use of fade in the CSS. That is the value provided in the name prop which means if you have for example:

    <transition name="slide-in" mode="out-in">
    

    then your CSS should have .slide-in-enter-active, .slide-in-enter-leave, and so on.