效果图
RecursionMenu.vue
<script setup lang="ts">
import { defineProps, toRef } from "vue";
const props = defineProps({
data: Array,
});
const data = toRef(props, "data");
</script>
<template>
<template v-for="(item, index) in data" :key="index">
<template v-if="!item.meta.hidden">
<el-sub-menu
popper-class="MypopperClass"
:style="{ '--color': '#2BAFAE' }"
v-if="item.children && item.children.length > 0"
:index="item.path"
:key="item.path"
>
<template #title>
<el-icon color="#ffffff">
<i class="iconfont clm-renyuanguanli"></i>
</el-icon>
<span>{{ item.meta.title }}</span></template
>
<RecursionMenu :data="item.children"></RecursionMenu>
</el-sub-menu>
<el-menu-item v-else :index="item.path" :key="item.path">
<el-icon color="#ffffff">
<i class="iconfont clm-renyuanguanli"></i>
</el-icon>
<template #title>{{ item.meta.title }}</template></el-menu-item
>
</template>
</template>
</template>
<!-- <script></script> -->
layoutAside.vue
<script lang="ts" setup>
import { useRoute, useRouter } from "vue-router";
import RecursionMenu from "@/components/RecursionMenu";
const route = useRoute();
const router = useRouter();
</script>
<template>
<el-menu
class="mymenu el-menu-vertical-demo"
router
:default-active="route.path"
collapse-transition
show-timeout
hide-timeout
text-color="#ffffff"
:style="{ '--color': '#2BAFAE' }"
>
<el-menu-item index="/home">
<el-icon color="#ffffff">
<i class="iconfont clm-renyuanguanli"></i>
</el-icon>
<template #title>{{ "首页" }}</template></el-menu-item
>
<el-menu-item index="/DisplayPage">
<el-icon color="#ffffff">
<i class="iconfont icon-renyuanguanli"></i>
</el-icon>
<template #title>{{ "闭环展示" }}</template></el-menu-item
>
<RecursionMenu :data="router.options.routes"></RecursionMenu>
</el-menu>
</template>
<style lang="scss">
:root {
color1: var(--color);
}
.el-menu-vertical-demo:not(.el-menu--collapse) {
height: calc(100vh - 100px);
background: var(--color);
}
.mymenu {
.el-menu-item.is-active {
color: var(--el-menu-active-color);
background: greenyellow;
}
.el-sub-menu .el-menu-item.is-active {
color: var(--el-menu-active-color);
background: greenyellow;
}
.el-menu-item:hover {
background-color: #c9c7c7;
}
.el-sub-menu .el-menu-item:hover {
background-color: #c9c7c7;
}
.el-sub-menu.is-active .el-sub-menu__title {
border-bottom-color: #c9c7c7;
}
.el-sub-menu__title:hover {
background-color: #c9c7c7;
}
.el-sub-menu .el-menu-item {
height: var(--el-menu-sub-item-height);
line-height: var(--el-menu-sub-item-height);
background: var(--color);
}
.el-sub-menu {
background: var(--color);
}
}
.mymenu.el-menu {
border-right: solid 1px var(--el-menu-border-color);
list-style: none;
position: relative;
margin: 0;
padding-left: 0;
background-color: var(--color);
box-sizing: border-box;
}
.MypopperClass {
.el-menu--popup {
z-index: 100;
min-width: 200px;
border: none;
padding: 5px 0;
border-radius: var(--el-border-radius-small);
box-shadow: var(--el-box-shadow-light);
background: var(--menu-color);
}
.el-menu-item.is-active {
color: var(--el-menu-active-color);
background: greenyellow;
}
.el-sub-menu .el-menu-item.is-active {
color: var(--el-menu-active-color);
background: greenyellow;
}
.el-menu-item:hover {
background-color: #c9c7c7;
}
.el-sub-menu .el-menu-item:hover {
background-color: #c9c7c7;
}
.el-sub-menu.is-active .el-sub-menu__title {
border-bottom-color: #c9c7c7;
}
.el-sub-menu__title:hover {
background-color: #c9c7c7;
}
.el-sub-menu .el-menu-item {
height: var(--el-menu-sub-item-height);
line-height: var(--el-menu-sub-item-height);
background: var(--color);
}
.el-sub-menu {
background: var(--color);
}
}
</style>
路由文件
import { createRouter, createWebHistory } from "vue-router";
import Layout from "@/views/Layout/layoutIndex.vue";
export const constantRoutes = [
{
path: "/",
component: Layout, // 这是一个框架组件,顶部和侧边栏会固定加载
redirect: "/home", // 重定向的就是中间的内容部分
meta: {
title: "首页",
icon: "iconfont clm-renyuanguanli",
hidden: true,
keepAlive: false,
},
children: [
{
path: "/home",
component: () => import("@/views/homeIndex/homeIndex.vue"),
name: "home",
meta: {
title: "首页",
icon: "iconfont clm-renyuanguanli",
hidden: false,
keepAlive: false,
},
},
],
},
{
path: "/show",
component: Layout, // 这是一个框架组件,顶部和侧边栏会固定加载
redirect: "/DisplayPage", // 重定向的就是中间的内容部分
meta: {
title: "闭环展示",
icon: "iconfont clm-renyuanguanli",
hidden: true,
keepAlive: false,
},
children: [
{
path: "/DisplayPage",
component: () => import("@/views/DisplayPage/DisplayPage.vue"),
name: "DisplayPage",
meta: {
title: "闭环展示",
icon: "iconfont clm-renyuanguanli",
hidden: false,
keepAlive: false,
},
},
],
},
{
path: "/config",
component: Layout, // 这是一个框架组件,顶部和侧边栏会固定加载
redirect: "/oneTem", // 重定向的就是中间的内容部分
meta: {
title: "闭环配置",
icon: "iconfont clm-renyuanguanli",
hidden: false,
keepAlive: false,
},
children: [
{
path: "/oneTem",
component: () => import("@/views/config/oneTem.vue"),
name: "oneTem",
meta: {
title: "单次临时医嘱",
icon: "iconfont clm-renyuanguanli",
hidden: false,
keepAlive: false,
},
},
{
path: "/longTem",
component: () => import("@/views/config/longTem.vue"),
name: "longTem",
meta: {
title: "长期医嘱",
icon: "iconfont clm-renyuanguanli",
hidden: false,
keepAlive: false,
},
},
{
path: "/manyTem",
component: () => import("@/views/config/manyTem.vue"),
name: "manyTem",
meta: {
title: "多次临时医嘱",
icon: "iconfont clm-renyuanguanli",
hidden: false,
keepAlive: false,
},
},
],
},
];
const scrollBehavior = function (to: any, from: any, savedPosition: any) {
// savedPosition 会在你使用浏览器前进或后退按钮时候生效
// 这个跟你使用 router.go() 或 router.back() 效果一致
// 这也是为什么我在 tab 栏结构中放入了一个 点击回退 的按钮
if (savedPosition) {
return savedPosition;
} else {
// 如果不是通过上述行为切换组件,就会让页面回到顶部
return { x: 0, y: 0 };
}
};
const router = createRouter({
history: createWebHistory(),
scrollBehavior: scrollBehavior,
routes: constantRoutes,
});
export default router;