1、layout总体布局代码:

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
<template>
<div class="layout_container">
<!-- 左侧菜单 -->
<div class="layout_slider">
<Logo></Logo> <!-- logo和标题展示 -->
<!-- 展示菜单 -->
<!-- 滚动组件 -->
<el-scrollbar class="scrollbar"> <!-- 左侧菜单栏滚动 -->
<!-- 菜单组件-->
<el-menu
:collapse="LayOutSettingStore.fold ? true : false"
:default-active="$route.path"
background-color="#001529"
text-color="white"
active-text-color="yellowgreen"
>
<!--根据路由动态生成菜单-->
<Menu :menuList="userStore.menuRoutes"></Menu>
</el-menu>
</el-scrollbar>
</div>
<!-- 顶部导航 -->
<div
class="layout_tabbar"
:class="{ fold: LayOutSettingStore.fold ? true : false }"
>
<!-- layout组件的顶部导航tabbar -->
<Tabbar></Tabbar>
</div>
<!-- 内容展示区域 -->
<div
class="layout_main"
:class="{ fold: LayOutSettingStore.fold ? true : false }"
>
<Main></Main>
</div>
</div>
</template>

<script setup lang="ts">
//获取路由对象
import { useRoute } from 'vue-router'
//引入左侧菜单logo子组件
import Logo from './logo/index.vue'
//引入菜单组件
import Menu from './menu/index.vue'
//右侧内容展示区域
import Main from './main/index.vue'
//引入顶部tabbar组件
import Tabbar from './tabbar/index.vue'
//获取用户相关的小仓库
import useUserStore from '@/store/modules/user'
import useLayOutSettingStore from '@/store/modules/setting'
let userStore = useUserStore()
//获取layout配置仓库

let LayOutSettingStore = useLayOutSettingStore()

//获取路由对象
let $route = useRoute()
</script>

<script lang="ts">
export default {
name: 'Layout',
}
</script>
<style scoped lang="scss">
.layout_container {
width: 100%;
height: 100vh;

.layout_slider {
color: white;
width: $base-menu-width;
height: 100vh;
background: $base-menu-background;
transition: all 0.3s;

.scrollbar {
width: 100%;
height: calc(100vh - $base-menu-logo-height);

.el-menu {
border-right: none;
}
}
}

.layout_tabbar {
position: fixed;
width: calc(100% - $base-menu-width);
height: $base-tabbar-height;
top: 0px;
left: $base-menu-width;
transition: all 0.3s;
&.fold {
width: calc(100vw - $base-menu-min-width);
left: $base-menu-min-width;
}
}

.layout_main {
position: absolute;
width: calc(100% - $base-menu-width);
height: calc(100vh - $base-tabbar-height);
left: $base-menu-width;
top: $base-tabbar-height;
padding: 20px;
overflow: auto;
transition: all 0.3s;

&.fold {
width: calc(100vw - $base-menu-min-width);
left: $base-menu-min-width;
}
}
}
</style>

其中动态菜单栏的定义如下:

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
<template>
<template v-for="(item, index) in menuList" :key="item.path">
<!--没有子路由-->
<template v-if="!item.children">
<el-menu-item
:index="item.path"
v-if="!item.meta.hidden"
@click="goRoute"
>
<el-icon>
<component :is="item.meta.icon"></component>
</el-icon>
<template #title>
<span>{{ item.meta.title }}</span>
</template>
</el-menu-item>
</template>
<!-- 有子路由但是只有一个子路由 -->
<template v-if="item.children && item.children.length == 1">
<el-menu-item
:index="item.children[0].path"
v-if="!item.children[0].meta.hidden"
@click="goRoute"
>
<el-icon>
<component :is="item.children[0].meta.icon"></component>
</el-icon>
<template #title>
<span>{{ item.children[0].meta.title }}</span>
</template>
</el-menu-item>
</template>
<!-- 有子路由且个数大于一个1 -->
<el-sub-menu
:index="item.path"
v-if="item.children && item.children.length > 1"
>
<template #title>
<el-icon>
<component :is="item.meta.icon"></component>
</el-icon>
<span>{{ item.meta.title }}</span>
</template><!-- 含多个字路由 使用递归的思想 -->
<Menu :menuList="item.children"></Menu>
</el-sub-menu>
</template>
</template>

<script setup lang="ts">
import { useRouter } from 'vue-router'
//获取父组件传递过来的全部路由数组
defineProps(['menuList'])

//获取路由器对象
let $router = useRouter()
//点击菜单的回调
const goRoute = (vc: any) => {
//路由跳转
$router.push(vc.index)
}
</script>
<script lang="ts">
export default {
name: 'Menu',
}
</script>

<style scoped></style>