|
@@ -1,87 +1,59 @@
|
|
|
<template>
|
|
|
<a-layout style="min-height: 100vh">
|
|
|
- <a-layout-sider theme="dark" :width="160" :collapsed-width="48" collapsible :trigger="null"
|
|
|
- @collapse="evMenuSecondLongShow" v-model:collapsed="menuSecondLongShow">
|
|
|
- <div class="logo-layout">
|
|
|
+ <a-layout-sider theme="dark" :width="260" :collapsed-width="48" collapsible :trigger="null"
|
|
|
+ @collapse="evMenuSecondLongShow" v-model:collapsed="menuSecondLongShow" class="menus">
|
|
|
+ <div class="logo-layout" v-if="LayoutStore.setting.SidebarLogo">
|
|
|
<div class="logo">
|
|
|
- <img src="@/assets/images/logo.png" style="height: 26px; width: 26px;" />
|
|
|
- <h3 v-if="!menuSecondLongShow" style="margin-left: 10px;"> Easy life</h3>
|
|
|
+ <img src="@/assets/images/logo.png" />
|
|
|
</div>
|
|
|
+ <h3>Esay life</h3>
|
|
|
</div>
|
|
|
|
|
|
- <a-menu v-model:selectedKeys="menuTabSate" theme="dark" mode="inline" @mouseleave="evMouseleaveMenu">
|
|
|
- <a-menu-item v-for="routeItem in routesData" :key="routeItem.name"
|
|
|
- @mouseenter="evMenuGetFn(routeItem, 'mouseenter')" @click="changeRoutesItems(routeItem)">
|
|
|
+ <a-menu v-model:selectedKeys="selectedKeys" @subMenuClick="sublevel" :open-keys="openKeys">
|
|
|
+ <a-sub-menu v-for="routeItem in routesData" :key="routeItem.name">
|
|
|
<template #icon>
|
|
|
<svg-icon :icon="routeItem.meta.icon"></svg-icon>
|
|
|
</template>
|
|
|
- <span>{{ routeItem.meta.title }}</span>
|
|
|
- </a-menu-item>
|
|
|
+ <template #title>
|
|
|
+ <div @click="evGoPage(routeItem)">{{ routeItem.meta.title }}</div>
|
|
|
+ </template>
|
|
|
+ <!-- 二级路由 -->
|
|
|
+ <template v-if="routeItem?.children && routeItem?.children.length > 0">
|
|
|
+ <a-menu-item v-for="(item) in routeItem?.children" :key="item.name" @click.stop="evGoPage(item)">
|
|
|
+ {{ item.meta.title }}
|
|
|
+ <!-- 三级菜单 -->
|
|
|
+ <template v-if="item.children && item.children.length > 0">
|
|
|
+ <sub-menu :key="routeItem.name" :menu-info="item" @go="evGoPage" />
|
|
|
+ </template>
|
|
|
+ </a-menu-item>
|
|
|
+ </template>
|
|
|
+ <!-- 折叠图标 -->
|
|
|
+ <template #expand-icon-down>
|
|
|
+ <icon-down v-if="routeItem?.children && routeItem?.children.length > 0"></icon-down>
|
|
|
+ </template>
|
|
|
+ </a-sub-menu>
|
|
|
</a-menu>
|
|
|
</a-layout-sider>
|
|
|
-
|
|
|
- <a-layout>
|
|
|
- <a-layout-header class="layout-header">
|
|
|
- <LayoutHeader />
|
|
|
- </a-layout-header>
|
|
|
- <a-layout>
|
|
|
- <a-layout-sider id="layout-sider" :collapsed="false" :width="menuSecondData &&
|
|
|
- menuSecondData.children &&
|
|
|
- menuSecondData.children.length > 0
|
|
|
- ? 160
|
|
|
- : 0
|
|
|
- " @mouseleave="evMouseLeavesSubMenu">
|
|
|
- <a-menu :selectedKeys="routeItemSelectedKeys" id="layout-sider" theme="light" mode="vertical"
|
|
|
- :collapsed="false" :auto-open="true">
|
|
|
- <template v-for="routeItem in menuSecondData?.children || []">
|
|
|
- <a-menu-item v-if="!routeItem.children || routeItem.children.length === 0"
|
|
|
- :key="routeItem.name?.toString()" @click="evGoPage(routeItem)">
|
|
|
- <span class="menu-level-font">{{ routeItem.meta.title }}</span>
|
|
|
- </a-menu-item>
|
|
|
-
|
|
|
- <template v-else-if="routeItem.children && routeItem.children.length > 0">
|
|
|
- <sub-menu :key="routeItem.name" :menu-info="routeItem" @go="evGoPage" />
|
|
|
- </template>
|
|
|
- </template>
|
|
|
- </a-menu>
|
|
|
- </a-layout-sider>
|
|
|
-
|
|
|
- <main class="layout-content-main">
|
|
|
- <router-view v-slot="{ Component }" class="layout-content-router">
|
|
|
- <component :is="Component" key="Layout" />
|
|
|
- </router-view>
|
|
|
- </main>
|
|
|
- </a-layout>
|
|
|
- </a-layout>
|
|
|
</a-layout>
|
|
|
</template>
|
|
|
<script setup>
|
|
|
-import { ref, computed, h, reactive, onMounted, watch, nextTick } from "vue";
|
|
|
+import { onMounted, ref, watch } from "vue";
|
|
|
import { useRoute, useRouter } from "vue-router";
|
|
|
import { useSystemStore } from "@/store/modules/systemStore";
|
|
|
-import LayoutHeader from "@/components/Layout/components/layoutHeader/index.vue";
|
|
|
import subMenu from "@/components/Layout/components/subMenu/index.vue";
|
|
|
-import {RouterTagData} from '@/store/modules/routerTag.js'
|
|
|
-
|
|
|
-// 标签页仓库
|
|
|
-const settingStore = RouterTagData()
|
|
|
-
|
|
|
+import { RouterTagData } from '@/store/modules/routerTag.js'
|
|
|
+import { layoutSetting } from '@/store/modules/layoutSetting'
|
|
|
+const LayoutStore = layoutSetting()
|
|
|
+const routerTagData = RouterTagData()
|
|
|
const systemStore = useSystemStore();
|
|
|
-
|
|
|
const route = useRoute();
|
|
|
const router = useRouter();
|
|
|
-
|
|
|
+const selectedKeys = ref()
|
|
|
+const openKeys = ref([])
|
|
|
const menuSecondLongShow = ref(systemStore.menuSecondLongShow);
|
|
|
// 主菜单
|
|
|
const routesData = router.options.routes[0]?.children || [];
|
|
|
|
|
|
-const menuTabSate = ref([systemStore.getMenuTabSate || routesData[0].name]);
|
|
|
-//子菜单
|
|
|
-const menuSecondData = ref(systemStore.getRouteItem);
|
|
|
-// 选中的状态路由列表
|
|
|
-const menuSecondSelectedStatusData = ref(systemStore.getRouteItem);
|
|
|
-const routeItemSelectedKeys = ref();
|
|
|
-
|
|
|
const evMenuSecondLongShow = () => {
|
|
|
systemStore.setStateValue({
|
|
|
key: "menuSecondLongShow",
|
|
@@ -89,23 +61,6 @@ const evMenuSecondLongShow = () => {
|
|
|
localStorage: true,
|
|
|
});
|
|
|
};
|
|
|
-const evMouseleaveMenu = (e) => {
|
|
|
- if (
|
|
|
- e.relatedTarget?.offsetParent?.id &&
|
|
|
- e.relatedTarget?.offsetParent?.id == "layout-sider"
|
|
|
- )
|
|
|
- return;
|
|
|
- menuSecondData.value = menuSecondSelectedStatusData.value;
|
|
|
-};
|
|
|
-// 子菜单
|
|
|
-const evMouseLeavesSubMenu = () => {
|
|
|
- menuSecondData.value = menuSecondSelectedStatusData.value;
|
|
|
-};
|
|
|
-// 鼠标滑动上去更新菜单栏 目前先屏蔽
|
|
|
-const evMenuGetFn = (routeItem, type) => {
|
|
|
- // menuSecondData.value = routeItem;
|
|
|
- // console.log(routeItem);
|
|
|
-};
|
|
|
|
|
|
// 查找最下级
|
|
|
const findPath = (data) => {
|
|
@@ -116,55 +71,96 @@ const findPath = (data) => {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
-// 主路由 状态
|
|
|
-const changeRoutesItems = (e) => {
|
|
|
- const item = findPath(e);
|
|
|
- evGoPage(item);
|
|
|
-};
|
|
|
-
|
|
|
// 跳转路由
|
|
|
const evGoPage = async (routeItem) => {
|
|
|
- // settingStore.tagsPushData(routeItem);
|
|
|
- await router.push({
|
|
|
- name: routeItem.name,
|
|
|
- });
|
|
|
- menuTabSate.value = [route.matched[1].name];
|
|
|
+ selectedKeys.value = [routeItem.name]
|
|
|
+ openKeys.value = [routeItem.name]
|
|
|
+ if (!routeItem.children) {
|
|
|
+ await router.push({
|
|
|
+ path: routeItem.path,
|
|
|
+ });
|
|
|
+ if (LayoutStore.setting.HeadNavigationBar) {
|
|
|
+ routerTagData.tagsPushData(routeItem)
|
|
|
+ routerTagData.getDefault(routeItem.name)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
systemStore.setStateValue({
|
|
|
key: "menuTabSate",
|
|
|
- value: menuTabSate.value[0] || "",
|
|
|
+ value: routeItem.name || "",
|
|
|
localStorage: true,
|
|
|
});
|
|
|
|
|
|
- menuSecondSelectedStatusData.value = routesData.find(
|
|
|
- (item) => item.name == menuTabSate.value
|
|
|
- );
|
|
|
- menuSecondData.value = menuSecondSelectedStatusData.value;
|
|
|
systemStore.setStateValue({
|
|
|
key: "routeItem",
|
|
|
- value: JSON.stringify(menuSecondData.value),
|
|
|
+ value: JSON.stringify(routeItem),
|
|
|
localStorage: true,
|
|
|
});
|
|
|
};
|
|
|
|
|
|
-watch(
|
|
|
- route,
|
|
|
- (val) => {
|
|
|
- if (val.name) {
|
|
|
- routeItemSelectedKeys.value = [val.name];
|
|
|
- }
|
|
|
- },
|
|
|
- { immediate: true }
|
|
|
-);
|
|
|
+watch(route, val => {
|
|
|
+ if (val) {
|
|
|
+ selectedKeys.value = [val.name]
|
|
|
+ routesData.forEach(res => {
|
|
|
+ if (res.children && res.children.length > 0) {
|
|
|
+ res.children.forEach(item => {
|
|
|
+ if (item.name == val.name) {
|
|
|
+ openKeys.value = [res.name];
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+}, { immediate: true })
|
|
|
+
|
|
|
+
|
|
|
</script>
|
|
|
<style scoped lang="less">
|
|
|
-.layout-header {
|
|
|
- height: 48px;
|
|
|
- background: @bg_color_2;
|
|
|
- padding-inline: 10px;
|
|
|
- box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
|
|
|
- z-index: 9;
|
|
|
+.menus {
|
|
|
+ background-color: #0b3d7f !important;
|
|
|
+
|
|
|
+ ::v-deep .arco-menu-inner {
|
|
|
+ background-color: #0b3d7f;
|
|
|
+
|
|
|
+ .arco-menu-has-icon {
|
|
|
+ background: #0b3d7f;
|
|
|
+ color: #fff;
|
|
|
+
|
|
|
+ .arco-menu-icon {
|
|
|
+ color: #fff;
|
|
|
+ }
|
|
|
+
|
|
|
+ .arco-menu-icon-suffix {
|
|
|
+ svg {
|
|
|
+ color: #fff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .arco-menu-item {
|
|
|
+ background-color: #0b3d7f;
|
|
|
+ color: #fff;
|
|
|
+ }
|
|
|
+
|
|
|
+ .arco-menu-inline-content {
|
|
|
+ .arco-menu-item-inner {
|
|
|
+ padding-left: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .arco-menu-selected {
|
|
|
+ background-color: #FFF;
|
|
|
+ color: #000;
|
|
|
+
|
|
|
+ .arco-icon {
|
|
|
+ color: #fff !important;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
+
|
|
|
.ant-layout-content {
|
|
|
height: auto;
|
|
|
min-height: auto;
|
|
@@ -172,16 +168,7 @@ watch(
|
|
|
padding: 0 20px;
|
|
|
}
|
|
|
|
|
|
-.layout-content-main {
|
|
|
- flex: 1;
|
|
|
- padding: 0 1.2rem 1.6rem 1.2rem;
|
|
|
- margin: 1.1rem 0 0rem 0;
|
|
|
- overflow-y: auto;
|
|
|
- overflow: overlay;
|
|
|
- height: 95%;
|
|
|
- display: flex;
|
|
|
- flex-wrap: wrap;
|
|
|
-}
|
|
|
+
|
|
|
|
|
|
.logo-layout {
|
|
|
height: 64px;
|
|
@@ -191,16 +178,23 @@ watch(
|
|
|
justify-content: center;
|
|
|
|
|
|
.logo {
|
|
|
- width: 100%;
|
|
|
- height: 32px;
|
|
|
+ width: 36px;
|
|
|
+ height: 36px;
|
|
|
display: flex;
|
|
|
justify-content: center;
|
|
|
align-items: center;
|
|
|
|
|
|
- h3 {
|
|
|
- white-space: nowrap;
|
|
|
+ img {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ h3 {
|
|
|
+ color: #fff;
|
|
|
+ margin-left: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
.arco-layout {
|
|
@@ -227,12 +221,6 @@ watch(
|
|
|
background-color: @bg_color_3;
|
|
|
}
|
|
|
|
|
|
-:deep(.layout-content-router) {
|
|
|
- padding: 0 1rem 1rem 1rem;
|
|
|
- background-color: @bg_color_4;
|
|
|
- box-sizing: border-box;
|
|
|
- width: 100%;
|
|
|
-}
|
|
|
|
|
|
:deep(.arco-menu-inline-content) {
|
|
|
.arco-menu-selected {
|