123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- <script lang="ts" setup>
- import type { VNode } from 'vue';
- import type {
- RouteLocationNormalizedLoaded,
- RouteLocationNormalizedLoadedGeneric,
- } from 'vue-router';
- import { computed } from 'vue';
- import { RouterView } from 'vue-router';
- import { preferences, usePreferences } from '@vben/preferences';
- import { storeToRefs, useTabbarStore } from '@vben/stores';
- import { IFrameRouterView } from '../../iframe';
- defineOptions({ name: 'LayoutContent' });
- const tabbarStore = useTabbarStore();
- const { keepAlive } = usePreferences();
- const { getCachedTabs, getExcludeCachedTabs, renderRouteView } =
- storeToRefs(tabbarStore);
- /**
- * 是否使用动画
- */
- const getEnabledTransition = computed(() => {
- const { transition } = preferences;
- const transitionName = transition.name;
- return transitionName && transition.enable;
- });
- // 页面切换动画
- function getTransitionName(_route: RouteLocationNormalizedLoaded) {
- // 如果偏好设置未设置,则不使用动画
- const { tabbar, transition } = preferences;
- const transitionName = transition.name;
- if (!transitionName || !transition.enable) {
- return;
- }
- // 标签页未启用或者未开启缓存,则使用全局配置动画
- if (!tabbar.enable || !keepAlive) {
- return transitionName;
- }
- // 如果页面已经加载过,则不使用动画
- // if (route.meta.loaded) {
- // return;
- // }
- // 已经打开且已经加载过的页面不使用动画
- // const inTabs = getCachedTabs.value.includes(route.name as string);
- // return inTabs && route.meta.loaded ? undefined : transitionName;
- return transitionName;
- }
- /**
- * 转换组件,自动添加 name
- * @param component
- */
- function transformComponent(
- component: VNode,
- route: RouteLocationNormalizedLoadedGeneric,
- ) {
- // 组件视图未找到,如果有设置后备视图,则返回后备视图,如果没有,则抛出错误
- if (!component) {
- console.error(
- 'Component view not found,please check the route configuration',
- );
- return undefined;
- }
- const routeName = route.name as string;
- // 如果组件没有 name,则直接返回
- if (!routeName) {
- return component;
- }
- const componentName = (component?.type as any)?.name;
- // 已经设置过 name,则直接返回
- if (componentName) {
- return component;
- }
- // componentName 与 routeName 一致,则直接返回
- if (componentName === routeName) {
- return component;
- }
- // 设置 name
- component.type ||= {};
- (component.type as any).name = routeName;
- return component;
- }
- </script>
- <template>
- <div class="relative h-full">
- <IFrameRouterView />
- <RouterView v-slot="{ Component, route }">
- <Transition
- v-if="getEnabledTransition"
- :name="getTransitionName(route)"
- appear
- mode="out-in"
- >
- <KeepAlive
- v-if="keepAlive"
- :exclude="getExcludeCachedTabs"
- :include="getCachedTabs"
- >
- <component
- :is="transformComponent(Component, route)"
- v-if="renderRouteView"
- v-show="!route.meta.iframeSrc"
- :key="route.fullPath"
- />
- </KeepAlive>
- <component
- :is="Component"
- v-else-if="renderRouteView"
- :key="route.fullPath"
- />
- </Transition>
- <template v-else>
- <KeepAlive
- v-if="keepAlive"
- :exclude="getExcludeCachedTabs"
- :include="getCachedTabs"
- >
- <component
- :is="transformComponent(Component, route)"
- v-if="renderRouteView"
- v-show="!route.meta.iframeSrc"
- :key="route.fullPath"
- />
- </KeepAlive>
- <component
- :is="Component"
- v-else-if="renderRouteView"
- :key="route.fullPath"
- />
- </template>
- </RouterView>
- </div>
- </template>
|