search

Home  >  Q&A  >  body text

Vue transitions don't work with router-link and $router.push

I have 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 files:

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 the app and click on any link, whether using $router.push("/dashboard"); or router-link(to ="/dashboard" active-class="active") . I've checked many other questions and tutorials but unfortunately it still doesn't work. Any idea why the conversion isn't happening?

P粉253518620P粉253518620344 days ago601

reply all(2)I'll reply

  • P粉504920992

    P粉5049209922023-12-27 11:48:13

    Change:

    <component :is="Component" />
    

    to

    <component :key="$route.path" :is="Component"/>
    

    The transformation does not detect changes to the view, so you need to provide something that can change. Also, remember that fade must be the actual animation in CSS, for example:

        .fade-enter-active
        {
            animation: fade 0.25s;
        }
    
        .fade-leave-active
        {
            animation: fade 0.25s reverse;
        }
    
        @keyframes fade 
        {
            from
            {
                opacity: 0%;
            }
    
            to
            {
                opacity: 100%;
            }
        }
    

    reply
    0
  • P粉659518294

    P粉6595182942023-12-27 00:37:55

    There are some things you can change in the code.

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

    Secondly, you need to change the name property to a static property. Writing :name="fade" means that you pass the value of the variable fade to name. Based on your code, I assume fade is not a variable but a string, which means you need to change the prop to name="fade". Learn more about static and dynamic props.

    Finally, transitions require the use of CSS. Since you are declaring a named transformation, 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;
    }
    

    Pay attention to the use of fade in CSS. This is the value provided in the name attribute, which means if you have:

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

    Then your CSS should have .slide-in-enter-active, .slide-in-enter-leave, etc.

    reply
    0
  • Cancelreply