index.vue
3.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<template>
<el-container class="app-layout">
<!-- 侧边栏 -->
<el-aside :width="sidebarWidth" class="sidebar-container">
<Sidebar />
</el-aside>
<el-container>
<!-- 顶部导航栏 -->
<el-header class="header-container">
<Header />
</el-header>
<!-- 面包屑导航 -->
<el-breadcrumb class="breadcrumb-container" separator="/">
<el-breadcrumb-item
v-for="item in breadcrumbList"
:key="item.path"
:to="item.path"
>
<el-icon v-if="item.icon" class="breadcrumb-icon">
<component :is="item.icon" />
</el-icon>
{{ item.title }}
</el-breadcrumb-item>
</el-breadcrumb>
<!-- 主内容区域 -->
<el-main class="main-container">
<router-view v-slot="{ Component }">
<transition name="fade-transform" mode="out-in">
<component :is="Component" />
</transition>
</router-view>
</el-main>
</el-container>
</el-container>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { useRoute } from 'vue-router'
import { useAppStore } from '@/stores/modules/app'
import Sidebar from '@/components/layout/Sidebar.vue'
import Header from '@/components/layout/Header.vue'
import type { BreadcrumbItem } from '@/types'
const route = useRoute()
const appStore = useAppStore()
// 侧边栏宽度
const sidebarWidth = computed(() => {
return appStore.sidebarCollapsed ? '64px' : '210px'
})
// 面包屑导航列表
const breadcrumbList = computed<BreadcrumbItem[]>(() => {
const matched = route.matched.filter(item => item.meta && item.meta.title)
const breadcrumbs: BreadcrumbItem[] = []
// 添加首页
breadcrumbs.push({
title: '首页',
path: '/dashboard'
})
// 添加当前路由的面包屑
matched.forEach(item => {
if (item.meta?.title && item.meta.title !== '首页') {
breadcrumbs.push({
title: item.meta.title as string,
path: item.path,
icon: item.meta.icon as string
})
}
})
return breadcrumbs
})
</script>
<style lang="scss" scoped>
.app-layout {
height: 100vh;
.sidebar-container {
background-color: var(--el-bg-color);
border-right: 1px solid var(--el-border-color-lighter);
transition: width 0.3s ease;
}
.header-container {
background-color: var(--el-bg-color);
border-bottom: 1px solid var(--el-border-color-lighter);
padding: 0 var(--el-spacing-base);
height: var(--header-height) !important;
line-height: var(--header-height);
}
.breadcrumb-container {
height: var(--breadcrumb-height);
line-height: var(--breadcrumb-height);
padding: 0 var(--el-spacing-base);
background-color: var(--el-bg-color);
border-bottom: 1px solid var(--el-border-color-lighter);
.breadcrumb-icon {
margin-right: 4px;
}
}
.main-container {
background-color: var(--el-bg-color-page);
padding: 0;
overflow-y: auto;
}
}
// 页面切换动画
.fade-transform-enter-active,
.fade-transform-leave-active {
transition: all 0.3s ease;
}
.fade-transform-enter-from {
opacity: 0;
transform: translateX(30px);
}
.fade-transform-leave-to {
opacity: 0;
transform: translateX(-30px);
}
</style>