|
|
@@ -1,148 +1,9 @@
|
|
|
-<!-- 带有二级菜单的layout -->
|
|
|
<template>
|
|
|
- <div class="component-container home-container">
|
|
|
- <aside class="aside">
|
|
|
- <header class="aside__header" />
|
|
|
- <main class="aside__main">
|
|
|
- <el-menu :default-active="selectedKeys" :default-openeds="openKeys" router class="el-menu-vertical">
|
|
|
- <template v-for="item in subMenus" :key="item.name">
|
|
|
- <el-sub-menu v-if="item.children" :index="item.path">
|
|
|
- <template #title>
|
|
|
- <component v-if="item.meta?.icon" :is="item.meta.icon" />
|
|
|
- <span class="menu-title">{{ item.meta?.title }}</span>
|
|
|
- </template>
|
|
|
- <el-menu-item v-for="child in item.children" :key="child.name" :index="child.path">
|
|
|
- <div style="margin-left: 12px">
|
|
|
- {{ child.meta?.title }}
|
|
|
- </div>
|
|
|
- </el-menu-item>
|
|
|
- </el-sub-menu>
|
|
|
- <el-menu-item v-else :index="item.path">
|
|
|
- <component v-if="item.meta?.icon" :is="item.meta?.icon" />
|
|
|
- <span class="menu-title">
|
|
|
- {{ item.meta?.title }}
|
|
|
- </span>
|
|
|
- </el-menu-item>
|
|
|
- </template>
|
|
|
- </el-menu>
|
|
|
- </main>
|
|
|
- </aside>
|
|
|
- <div class="main">
|
|
|
- <router-view></router-view>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
+ <LeftMenu>
|
|
|
+ <router-view></router-view>
|
|
|
+ </LeftMenu>
|
|
|
</template>
|
|
|
-
|
|
|
-<script setup lang="ts">
|
|
|
- import { ref, watch, computed } from 'vue';
|
|
|
- import { useRoute } from 'vue-router';
|
|
|
-
|
|
|
- // 当前路由
|
|
|
- const currentRoute = useRoute();
|
|
|
- const activeMenu = currentRoute.meta?.activeMenu || null; // activeMenu undefined,null 或 空字符串,统一变为 null。
|
|
|
- const selectedKeys = ref<string>((activeMenu ?? currentRoute.path) as string);
|
|
|
-
|
|
|
- const openKeys = ref<string[]>([]);
|
|
|
-
|
|
|
- // 将菜单数组过滤掉隐藏的菜单
|
|
|
- const filterHiddenMenus = (menus: any[]) => {
|
|
|
- return menus.filter((menu) => !menu.meta?.hidden);
|
|
|
- };
|
|
|
-
|
|
|
- function filterHiddenItems(arr: any[]): any[] {
|
|
|
- return arr.filter((item) => {
|
|
|
- if (item.meta && item.meta.hidden) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- if (item.children && Array.isArray(item.children)) {
|
|
|
- item.children = filterHiddenItems(item.children);
|
|
|
- }
|
|
|
- return true;
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- const subMenus = computed(() => {
|
|
|
- return filterHiddenItems(currentRoute.matched[0].children);
|
|
|
- });
|
|
|
-
|
|
|
- // 跟随页面路由变化,切换菜单选中状态
|
|
|
- watch(
|
|
|
- () => currentRoute.fullPath,
|
|
|
- () => {
|
|
|
- const matched = currentRoute.matched;
|
|
|
- openKeys.value = matched.map((item) => item.name) as string[];
|
|
|
- const activeMenu: string = (currentRoute.meta?.activeMenu as string) || '';
|
|
|
- selectedKeys.value = activeMenu ? activeMenu : (currentRoute.path as string);
|
|
|
- },
|
|
|
- );
|
|
|
+<script lang="ts" setup>
|
|
|
+ import LeftMenu from './components/left-menu/LeftMenu.vue';
|
|
|
</script>
|
|
|
-
|
|
|
-<style scoped lang="scss">
|
|
|
- :deep(.el-menu-item) {
|
|
|
- transition: unset;
|
|
|
- }
|
|
|
- .home-container {
|
|
|
- display: flex;
|
|
|
- gap: 10px;
|
|
|
- padding: 10px;
|
|
|
- height: 100%;
|
|
|
- }
|
|
|
- .aside {
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- width: 228px;
|
|
|
- height: 100%;
|
|
|
- flex-shrink: 0;
|
|
|
- border-radius: 4px;
|
|
|
- background-color: $white-color;
|
|
|
- &__header {
|
|
|
- width: inherit;
|
|
|
- height: 10px;
|
|
|
- flex-shrink: 0;
|
|
|
- }
|
|
|
- &__main {
|
|
|
- width: inherit;
|
|
|
- flex: 1;
|
|
|
- }
|
|
|
- }
|
|
|
- .main {
|
|
|
- flex: 1;
|
|
|
- overflow: auto;
|
|
|
- border-radius: 4px;
|
|
|
- }
|
|
|
- .el-menu-vertical {
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- border: none;
|
|
|
- border-radius: 4px;
|
|
|
- .el-menu-item,
|
|
|
- :deep(.el-sub-menu__title) {
|
|
|
- font-size: 16px;
|
|
|
- color: #333;
|
|
|
- }
|
|
|
- .el-menu-item.is-active {
|
|
|
- color: $white-color;
|
|
|
- background-color: $primary-color;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .el-menu-item,
|
|
|
- .el-sub-menu {
|
|
|
- svg {
|
|
|
- color: $primary-color;
|
|
|
- }
|
|
|
- }
|
|
|
- .el-menu-item {
|
|
|
- &.is-active {
|
|
|
- svg {
|
|
|
- color: #fff;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- :deep(.el-sub-menu__title),
|
|
|
- :deep(.el-menu-item) {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- gap: 12px;
|
|
|
- }
|
|
|
-</style>
|
|
|
+<style scoped></style>
|