Vue3中Transition组件导致路由跳转失效的问题排查
Root Cause Analysis
The problem stems from the combination of nested parent routes with redirect, <transition mode="out-in">, and <keep-alive> in the shared Layout component. When navigating between /user and /order, the router processes dual redirects, triggering multiple navigation events. The out-in transition waits for the old component to fully exit before mounting the new one, but the redirect flow and component reuse disrupt this sequence, leading to empty router-view content.
Fixes & Workarounds
1. Replace Redirects with Default Child Routes
Eliminate extra navigation events by setting an empty path on child routes to make them the default for their parent:
const routes = [ { path: '/user', name: 'user', component: Layout, meta: { title: '111' }, children: [ { path: '', name: 'UserDetail', component: () => import('@/pages/order/userOrder.vue') }, { path: 'detail', redirect: '' } // Optional: Preserve /user/detail path ] }, { path: '/order', name: 'order', component: Layout, meta: { title: '222' }, children: [ { path: '', name: 'OrderDetail', component: () => import('@/pages/order/index.vue') }, { path: 'detail', redirect: '' } // Optional: Preserve /order/detail path ] } ]
2. Add a Unique Key to the Router-View
Force Vue to re-render the router-view on full path changes, ensuring proper component switching:
<router-view :key="$route.fullPath" v-slot="{ Component }"> <transition name="fade" mode="out-in"> <keep-alive> <component :is="Component" /> </keep-alive> </transition> </router-view>
3. Adjust Transition Mode
If mode="out-in" isn't essential, remove it to resolve timing conflicts:
<router-view v-slot="{ Component }"> <transition name="fade"> <keep-alive> <component :is="Component" /> </keep-alive> </transition> </router-view>
4. Ensure Components Have Unique Names
Define distinct names for child components so <keep-alive> can cache them correctly:
For userOrder.vue:
<script setup> defineOptions({ name: 'UserOrder' }) // Component code </script>
For index.vue:
<script setup> defineOptions({ name: 'OrderDetail' }) // Component code </script>
Then explicitly specify cached components:
<keep-alive include="UserOrder,OrderDetail"> <component :is="Component" /> </keep-alive>
内容的提问来源于stack exchange,提问作者肉蛋充肌

