Skip to content

Commit 2652572

Browse files
committed
refactor: ♻️ 布局代码目录结构重构
1 parent 6730608 commit 2652572

File tree

9 files changed

+98
-111
lines changed

9 files changed

+98
-111
lines changed

src/layouts/components/AppMain/index.vue

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
</transition>
1010
</template>
1111
</router-view>
12+
13+
<!-- 返回顶部按钮 -->
14+
<el-backtop target=".app-main">
15+
<div class="i-svg:backtop w-6 h-6" />
16+
</el-backtop>
1217
</section>
1318
</template>
1419

src/layouts/index.vue

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,36 @@
11
<template>
2-
<div class="layout-wrapper">
3-
<component :is="currentLayoutComponent" />
2+
<div class="layout" :class="layoutClass">
3+
<!-- 移动端遮罩层 -->
4+
<div v-if="isMobile && isSidebarOpen" class="layout__overlay" @click="closeSidebar" />
45

5-
<!-- 设置面板 - 独立于布局组件 -->
6-
<Settings v-if="isShowSettings" />
6+
<!-- 布局内容插槽 -->
7+
<slot></slot>
78
</div>
89
</template>
910

1011
<script setup lang="ts">
11-
import { computed } from "vue";
12-
import { useRoute } from "vue-router";
13-
import { useLayout } from "@/composables/layout/useLayout";
14-
import LeftLayout from "./views/LeftLayout.vue";
15-
import TopLayout from "./views/TopLayout.vue";
16-
import MixLayout from "./views/MixLayout.vue";
17-
import Settings from "./components/Settings/index.vue";
18-
import { LayoutMode } from "@/enums/settings/layout.enum";
19-
import { defaultSettings } from "@/settings";
12+
import { useLayout, useLayoutResponsive } from "@/composables";
2013
21-
const { currentLayout } = useLayout();
22-
const route = useRoute();
14+
// 布局相关
15+
const { layoutClass, isSidebarOpen, closeSidebar } = useLayout();
2316
24-
// 根据当前布局模式选择对应的组件
25-
const currentLayoutComponent = computed(() => {
26-
const override = route.meta?.layout as LayoutMode | undefined;
27-
const layoutToUse = override ?? currentLayout.value;
28-
switch (layoutToUse) {
29-
case LayoutMode.TOP:
30-
return TopLayout;
31-
case LayoutMode.MIX:
32-
return MixLayout;
33-
case LayoutMode.LEFT:
34-
default:
35-
return LeftLayout;
36-
}
37-
});
38-
39-
// 是否显示设置面板
40-
const isShowSettings = computed(() => defaultSettings.showSettings);
17+
// 响应式布局
18+
const { isMobile } = useLayoutResponsive();
4119
</script>
4220

4321
<style lang="scss" scoped>
44-
.layout-wrapper {
22+
.layout {
4523
width: 100%;
4624
height: 100%;
25+
26+
&__overlay {
27+
position: fixed;
28+
top: 0;
29+
left: 0;
30+
z-index: 999;
31+
width: 100%;
32+
height: 100%;
33+
background-color: rgba(0, 0, 0, 0.3);
34+
}
4735
}
4836
</style>

src/layouts/layouts/BaseLayout.vue

Lines changed: 0 additions & 41 deletions
This file was deleted.

src/layouts/modes/index.vue

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<template>
2+
<div class="layout-wrapper">
3+
<component :is="currentLayoutComponent" />
4+
5+
<!-- 设置面板 - 独立于布局组件 -->
6+
<Settings v-if="isShowSettings" />
7+
</div>
8+
</template>
9+
10+
<script setup lang="ts">
11+
import { useRoute } from "vue-router";
12+
import { useLayout } from "@/composables/layout/useLayout";
13+
import LeftLayout from "@/layouts/modes/left/index.vue";
14+
import TopLayout from "@/layouts/modes/top/index.vue";
15+
import MixLayout from "@/layouts/modes/mix/index.vue";
16+
import Settings from "../components/Settings/index.vue";
17+
import { LayoutMode } from "@/enums/settings/layout.enum";
18+
import { defaultSettings } from "@/settings";
19+
20+
const { currentLayout } = useLayout();
21+
const route = useRoute();
22+
23+
// 根据当前布局模式选择对应的组件
24+
const currentLayoutComponent = computed(() => {
25+
const override = route.meta?.layout as LayoutMode | undefined;
26+
const layoutToUse = override ?? currentLayout.value;
27+
switch (layoutToUse) {
28+
case LayoutMode.TOP:
29+
return TopLayout;
30+
case LayoutMode.MIX:
31+
return MixLayout;
32+
case LayoutMode.LEFT:
33+
default:
34+
return LeftLayout;
35+
}
36+
});
37+
38+
// 是否显示设置面板
39+
const isShowSettings = computed(() => defaultSettings.showSettings);
40+
</script>
41+
42+
<style lang="scss" scoped>
43+
.layout-wrapper {
44+
width: 100%;
45+
height: 100%;
46+
}
47+
</style>
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@
3030
<script setup lang="ts">
3131
import { useLayout } from "@/composables/layout/useLayout";
3232
import { useLayoutMenu } from "@/composables/layout/useLayoutMenu";
33-
import BaseLayout from "./BaseLayout.vue";
34-
import AppLogo from "../components/AppLogo/index.vue";
35-
import NavBar from "../components/NavBar/index.vue";
36-
import TagsView from "../components/TagsView/index.vue";
37-
import AppMain from "../components/AppMain/index.vue";
38-
import BasicMenu from "../components/Menu/BasicMenu.vue";
33+
import BaseLayout from "@/layouts/index.vue";
34+
import AppLogo from "../../components/AppLogo/index.vue";
35+
import NavBar from "../../components/NavBar/index.vue";
36+
import TagsView from "../../components/TagsView/index.vue";
37+
import AppMain from "../../components/AppMain/index.vue";
38+
import BasicMenu from "../../components/Menu/BasicMenu.vue";
3939
4040
// 布局相关参数
4141
const { isShowTagsView, isShowLogo, isSidebarOpen } = useLayout();
Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,17 @@
5858
</template>
5959

6060
<script setup lang="ts">
61+
import { computed, watch } from "vue";
6162
import { useRoute } from "vue-router";
6263
import { useWindowSize } from "@vueuse/core";
6364
import { useLayout, useLayoutMenu } from "@/composables";
64-
import BaseLayout from "./BaseLayout.vue";
65-
import AppLogo from "../components/AppLogo/index.vue";
66-
import MixTopMenu from "../components/Menu/MixTopMenu.vue";
67-
import NavbarActions from "../components/NavBar/components/NavbarActions.vue";
68-
import TagsView from "../components/TagsView/index.vue";
69-
import AppMain from "../components/AppMain/index.vue";
70-
import MenuItem from "../components/Menu/components/MenuItem.vue";
65+
import BaseLayout from "@/layouts/index.vue";
66+
import AppLogo from "../../components/AppLogo/index.vue";
67+
import MixTopMenu from "../../components/Menu/MixTopMenu.vue";
68+
import NavbarActions from "../../components/NavBar/components/NavbarActions.vue";
69+
import TagsView from "../../components/TagsView/index.vue";
70+
import AppMain from "../../components/AppMain/index.vue";
71+
import MenuItem from "../../components/Menu/components/MenuItem.vue";
7172
import Hamburger from "@/components/Hamburger/index.vue";
7273
import variables from "@/styles/variables.module.scss";
7374
import { isExternal } from "@/utils/index";
@@ -91,8 +92,8 @@ const isLogoCollapsed = computed(() => width.value < 768);
9192
const activeLeftMenuPath = computed(() => {
9293
const { meta, path } = route;
9394
// 如果设置了activeMenu,则使用
94-
if (meta?.activeMenu && typeof meta.activeMenu === "string") {
95-
return meta.activeMenu;
95+
if ((meta?.activeMenu as unknown as string) && typeof meta.activeMenu === "string") {
96+
return meta.activeMenu as unknown as string;
9697
}
9798
return path;
9899
});
@@ -116,26 +117,16 @@ function resolvePath(routePath: string) {
116117
watch(
117118
() => route.path,
118119
(newPath) => {
119-
console.log("📍 Route changed in MixLayout:", newPath);
120-
121120
// 获取顶级路径
122121
const topMenuPath =
123122
newPath.split("/").filter(Boolean).length > 1 ? newPath.match(/^\/[^/]+/)?.[0] || "/" : "/";
124123
125124
// 如果当前路径属于当前激活的顶部菜单
126125
if (newPath.startsWith(activeTopMenuPath.value)) {
127-
console.log("📍 Route is under active top menu, ensuring menu item is activated");
126+
// no-op
128127
}
129128
// 如果路径改变了顶级菜单,确保顶部菜单和左侧菜单都更新
130129
else if (topMenuPath !== activeTopMenuPath.value) {
131-
console.log(
132-
"📍 Top menu changed, updating active menu from:",
133-
activeTopMenuPath.value,
134-
"to:",
135-
topMenuPath
136-
);
137-
138-
// 主动更新顶部菜单和左侧菜单
139130
const appStore = useAppStore();
140131
const permissionStore = usePermissionStore();
141132
@@ -283,7 +274,6 @@ watch(
283274
}
284275
}
285276
}
286-
287277
:deep(.hasTagsView) {
288278
.app-main {
289279
height: calc(100vh - $navbar-height - $tags-view-height) !important;
Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,14 @@
2323
</template>
2424

2525
<script setup lang="ts">
26-
import { computed } from "vue";
27-
import { useWindowSize } from "@vueuse/core";
2826
import { useLayout } from "@/composables/layout/useLayout";
2927
import { useLayoutMenu } from "@/composables/layout/useLayoutMenu";
30-
import BaseLayout from "./BaseLayout.vue";
31-
import AppLogo from "../components/AppLogo/index.vue";
32-
import BasicMenu from "../components/Menu/BasicMenu.vue";
33-
import NavbarActions from "../components/NavBar/components/NavbarActions.vue";
34-
import TagsView from "../components/TagsView/index.vue";
35-
import AppMain from "../components/AppMain/index.vue";
28+
import BaseLayout from "@/layouts/index.vue";
29+
import AppLogo from "../../components/AppLogo/index.vue";
30+
import BasicMenu from "../../components/Menu/BasicMenu.vue";
31+
import NavbarActions from "../../components/NavBar/components/NavbarActions.vue";
32+
import TagsView from "../../components/TagsView/index.vue";
33+
import AppMain from "../../components/AppMain/index.vue";
3634
3735
// 布局相关参数
3836
const { isShowTagsView, isShowLogo } = useLayout();

src/router/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { App } from "vue";
22
import { createRouter, createWebHashHistory, type RouteRecordRaw } from "vue-router";
33

4-
export const Layout = () => import("@/layouts/index.vue");
4+
export const Layout = () => import("@/layouts/modes/index.vue");
55

66
// 静态路由
77
export const constantRoutes: RouteRecordRaw[] = [

src/store/modules/permission-store.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import router from "@/router";
55

66
import MenuAPI, { type RouteVO } from "@/api/system/menu-api";
77
const modules = import.meta.glob("../../views/**/**.vue");
8-
const Layout = () => import("@/layouts/index.vue");
8+
const Layout = () => import("@/layouts/modes/index.vue");
99

1010
export const usePermissionStore = defineStore("permission", () => {
1111
// 所有路由(静态路由 + 动态路由)

0 commit comments

Comments
 (0)