feat: 项目结构重构优化
This commit is contained in:
91
src/layouts/components/LayoutMain.vue
Normal file
91
src/layouts/components/LayoutMain.vue
Normal file
@@ -0,0 +1,91 @@
|
||||
<template>
|
||||
<section class="app-main" :style="{ height: appMainHeight }">
|
||||
<router-view>
|
||||
<template #default="{ Component, route }">
|
||||
<transition enter-active-class="animate__animated animate__fadeIn" mode="out-in">
|
||||
<keep-alive :include="cachedViews">
|
||||
<component :is="currentComponent(Component, route)" :key="route.fullPath" />
|
||||
</keep-alive>
|
||||
</transition>
|
||||
</template>
|
||||
</router-view>
|
||||
|
||||
<!-- 返回顶部按钮 -->
|
||||
<el-backtop target=".app-main">
|
||||
<div class="i-svg:backtop w-6 h-6" />
|
||||
</el-backtop>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { type RouteLocationNormalized } from "vue-router";
|
||||
import { useSettingsStore, useTagsViewStore } from "@/store";
|
||||
import variables from "@/styles/variables.module.scss";
|
||||
import Error404 from "@/views/error/404.vue";
|
||||
|
||||
const { cachedViews } = toRefs(useTagsViewStore());
|
||||
|
||||
// 当前组件
|
||||
const wrapperMap = new Map<string, Component>();
|
||||
const currentComponent = (component: Component, route: RouteLocationNormalized) => {
|
||||
if (!component) return;
|
||||
|
||||
const { fullPath: componentName } = route; // 使用路由路径作为组件名称
|
||||
let wrapper = wrapperMap.get(componentName);
|
||||
|
||||
if (!wrapper) {
|
||||
wrapper = {
|
||||
name: componentName,
|
||||
render: () => {
|
||||
try {
|
||||
return h(component);
|
||||
} catch (error) {
|
||||
console.error(`Error rendering component for route: ${componentName}`, error);
|
||||
return h(Error404);
|
||||
}
|
||||
},
|
||||
};
|
||||
wrapperMap.set(componentName, wrapper);
|
||||
}
|
||||
|
||||
// 添加组件数量限制
|
||||
if (wrapperMap.size > 100) {
|
||||
const firstKey = wrapperMap.keys().next().value;
|
||||
if (firstKey) {
|
||||
wrapperMap.delete(firstKey);
|
||||
}
|
||||
}
|
||||
|
||||
return h(wrapper);
|
||||
};
|
||||
|
||||
const appMainHeight = computed(() => {
|
||||
if (useSettingsStore().showTagsView) {
|
||||
return `calc(100vh - ${variables["navbar-height"]} - ${variables["tags-view-height"]})`;
|
||||
} else {
|
||||
return `calc(100vh - ${variables["navbar-height"]})`;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.app-main {
|
||||
position: relative;
|
||||
overflow-y: auto;
|
||||
background-color: var(--el-bg-color-page);
|
||||
|
||||
/* 布局切换动画优化 */
|
||||
&.animate__animated {
|
||||
animation-duration: 0.4s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
&.animate__fadeOut {
|
||||
animation-timing-function: ease-in;
|
||||
}
|
||||
|
||||
&.animate__fadeIn {
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user