Files
yudao-ui-admin-vben/packages/effects/layouts/src/basic/content/content.vue
Guillermo Sagar 6910c691f7 修复动画导致的白屏Bug (#8148)
首次页面加载正常,但是当通过页面点击切换路由的时候白屏,无法正常渲染子页面

 Vue Transition + KeepAlive 空白页 bug**: `<Transition mode="out-in">` + 条件渲染会导致路由切换空白页。`mode="out-in"` 要求旧元素完成 leave 动画后新元素才进入,但路由切换时条件渲染可能在动画前就移除了旧元素,导致 `<Transition>` 永远等待一个不存在的元素 → 死锁。**解决方案**: 移除 `mode="out-in"`(保留 Transition 动画),或在 `apps/web-antd/src/preferences.ts` 设置 `transition: { enable: false }` 关闭动画走 `v-else` 分支。
2026-07-16 09:35:25 +08:00

88 lines
2.4 KiB
Vue

<script lang="ts" setup>
import type { RouteLocationNormalizedLoadedGeneric } from 'vue-router';
import { unref } from 'vue';
import { RouterView } from 'vue-router';
import { usePreferences } from '@vben/preferences';
import { getTabKey, storeToRefs, useTabbarStore } from '@vben/stores';
import { transformComponent, useLayoutHook } from '../../hooks';
import { IFrameRouterView } from '../../iframe';
import { RouteCachedPage, RouteCachedView } from '../../route-cached';
defineOptions({ name: 'LayoutContent' });
const tabbarStore = useTabbarStore();
const { keepAlive } = usePreferences();
const { getCachedTabs, getExcludeCachedTabs, renderRouteView } =
storeToRefs(tabbarStore);
const { getEnabledTransition, getTransitionName } = useLayoutHook();
/**
* 是否显示component
* @param route
*/
const showComponent = (route: RouteLocationNormalizedLoadedGeneric) => {
return !route.meta.domCached && unref(renderRouteView);
};
</script>
<template>
<div class="relative h-full">
<IFrameRouterView />
<RouteCachedView />
<RouterView v-slot="{ Component, route }">
<RouteCachedPage
:component="Component"
:route="route"
v-if="route.meta.domCached"
/>
<Transition
v-if="getEnabledTransition"
:name="getTransitionName(route)"
appear
>
<KeepAlive
v-if="keepAlive"
:exclude="getExcludeCachedTabs"
:include="getCachedTabs"
>
<component
:is="transformComponent(Component, route)"
v-if="showComponent(route)"
v-show="!route.meta.iframeSrc"
:key="getTabKey(route)"
/>
</KeepAlive>
<component
:is="Component"
v-else-if="showComponent(route)"
:key="getTabKey(route)"
/>
</Transition>
<template v-else>
<KeepAlive
v-if="keepAlive"
:exclude="getExcludeCachedTabs"
:include="getCachedTabs"
>
<component
:is="transformComponent(Component, route)"
v-if="showComponent(route)"
v-show="!route.meta.iframeSrc"
:key="getTabKey(route)"
/>
</KeepAlive>
<component
:is="Component"
v-else-if="showComponent(route)"
:key="getTabKey(route)"
/>
</template>
</RouterView>
</div>
</template>