Search code examples
vue.jsvuejs2vue-routertransition

Vue transition failed when use group routes in vue-router


I want use group route and the nested routes mount at top level, so I found the issue1issue2 and fix the problem.

But when I added the transition tag for the <route-view> the transition is not work correctly by using group route.
Here is the full code https://codepen.io/changemyminds/pen/ExmLdBM

You click Home -> Profile and Profile -> Home the transition work correctly, but when you click User -> Role and Role -> User the transition work failed and just flashing.

enter image description here

Some code snippet.

Routes

const router = new VueRouter({
  routes: [
    { path: '/', name: 'Home', component: Home },
    { path: '/prfile', name: 'Profile', component: Profile },
    { 
      path: '/admin',
      name: 'Admin',
      component: { render: (h) => h("router-view") },
      redirect: "/admin/user",
      children: [         
        { path: 'user', name: 'User', component: User },
        { path: 'role', name: 'Role', component: Role }
      ]
    }
  ]
});

View

  <div>
    <h1>Correct Transition</h1>    
    <router-link :to="{ name: 'Home'}">
      <button>Home</button>
    </router-link>
   
    <router-link :to="{ name: 'Profile'}">
      <button>Profile</button>
    </router-link>    
 
  </div>
  <div>
    <h1>Failed Transition</h1>   
    <router-link :to="{ name: 'User'}">
      <button>User</button>
    </router-link>

    <router-link :to="{ name: 'Role'}">
      <button>Role</button>
    </router-link> 
  </div>
  
  <transition name="slide-fade">
    <router-view></router-view>
  </transition> 

CSS

.slide-fade-enter-active {
  transition: all .3s ease;
}
.slide-fade-leave-active {
  transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.slide-fade-enter, .slide-fade-leave-to
/* .slide-fade-leave-active for below version 2.1.8 */ {
  transform: translateX(10px);
  opacity: 0;
}

Seems the v-leave-active and v-leave-to is not working. Does anyone know why?


Solution

  • Finally, I found the problem because I lost the key on the parent <router-view>.

    If I set key with this.$route.path the Vue virtual DOM will different and will trigger the transition again.

    • View
    <div id="app">
      <!-- same tag bypass... -->
    
      <transition name="slide-fade">
        <router-view :key="key"></router-view>
      </transition>
    </div>
    
    • Routes
    <!-- same routes bypass... -->
    
    new Vue({
      el: "#app",
      router,
      computed: {
        key() {
          return this.$route.path;
        }
      }
    });
    

    https://codepen.io/changemyminds/pen/XWRqyEr