|
@@ -1,64 +1,111 @@
|
|
|
<template>
|
|
|
- <a-row class="grid-demo">
|
|
|
- <a-col :span="menuSecondData && menuSecondData && menuSecondData.length !== 0 ? 12 : 24"
|
|
|
- style="height: 100vh;background-color: #232324;">
|
|
|
- <div class="logo-layout" v-if="LayoutStore.setting.SidebarLogo">
|
|
|
+ <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">
|
|
|
<div class="logo">
|
|
|
- <img src="@/assets/images/logo.png" />
|
|
|
+ <img src="@/assets/images/logo.png" style="height: 26px; width: 26px;" />
|
|
|
+ <h3 v-if="!menuSecondLongShow" style="margin-left: 10px;"> Easy life</h3>
|
|
|
</div>
|
|
|
- <h3>Easy life</h3>
|
|
|
</div>
|
|
|
- <a-menu v-model:selectedKeys="menuTabSate" theme="dark" mode="inline">
|
|
|
- <a-menu-item v-for="routeItem in routesData" :key="routeItem.name" @click="changeRoutesItems(routeItem)">
|
|
|
+
|
|
|
+ <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)">
|
|
|
<template #icon>
|
|
|
<svg-icon :icon="routeItem.meta.icon"></svg-icon>
|
|
|
</template>
|
|
|
<span>{{ routeItem.meta.title }}</span>
|
|
|
</a-menu-item>
|
|
|
</a-menu>
|
|
|
- </a-col>
|
|
|
- <a-col :span="12" v-if="menuSecondData && menuSecondData && menuSecondData.length !== 0">
|
|
|
- <a-menu :selectedKeys="routeItemSelectedKeys" id="layout-sider" theme="light" mode="vertical" :collapsed="false"
|
|
|
- :auto-open="true" style="height: 100vh;color: #fff;">
|
|
|
- <template v-for="routeItem in menuSecondData">
|
|
|
- <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-col>
|
|
|
- </a-row>
|
|
|
+ </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 { 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'
|
|
|
-import { layoutSetting } from '@/store/modules/layoutSetting'
|
|
|
-const LayoutStore = layoutSetting()
|
|
|
+import {RouterTagData} from '@/store/modules/routerTag.js'
|
|
|
+
|
|
|
// 标签页仓库
|
|
|
-const routerTagData = RouterTagData()
|
|
|
+const settingStore = RouterTagData()
|
|
|
|
|
|
const systemStore = useSystemStore();
|
|
|
|
|
|
const route = useRoute();
|
|
|
const router = useRouter();
|
|
|
|
|
|
+const menuSecondLongShow = ref(systemStore.menuSecondLongShow);
|
|
|
// 主菜单
|
|
|
const routesData = router.options.routes[0]?.children || [];
|
|
|
|
|
|
-const menuTabSate = ref([routerTagData.getDefault]);
|
|
|
+const menuTabSate = ref([systemStore.getMenuTabSate || routesData[0].name]);
|
|
|
//子菜单
|
|
|
-const menuSecondData = ref([]);
|
|
|
+const menuSecondData = ref(systemStore.getRouteItem);
|
|
|
// 选中的状态路由列表
|
|
|
-
|
|
|
+const menuSecondSelectedStatusData = ref(systemStore.getRouteItem);
|
|
|
const routeItemSelectedKeys = ref();
|
|
|
|
|
|
+const evMenuSecondLongShow = () => {
|
|
|
+ systemStore.setStateValue({
|
|
|
+ key: "menuSecondLongShow",
|
|
|
+ value: menuSecondLongShow.value ? 1 : 0,
|
|
|
+ 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) => {
|
|
@@ -71,29 +118,30 @@ const findPath = (data) => {
|
|
|
|
|
|
// 主路由 状态
|
|
|
const changeRoutesItems = (e) => {
|
|
|
- // 储存当前路由
|
|
|
- systemStore.setStateValue({
|
|
|
- key: "routeItem",
|
|
|
- value: JSON.stringify(e),
|
|
|
- localStorage: true,
|
|
|
- });
|
|
|
- menuSecondData.value = e.children
|
|
|
const item = findPath(e);
|
|
|
evGoPage(item);
|
|
|
};
|
|
|
|
|
|
// 跳转路由
|
|
|
const evGoPage = async (routeItem) => {
|
|
|
+ // settingStore.tagsPushData(routeItem);
|
|
|
await router.push({
|
|
|
name: routeItem.name,
|
|
|
});
|
|
|
- if (LayoutStore.setting.HeadNavigationBar) {
|
|
|
- routerTagData.tagsPushData(routeItem)
|
|
|
- routerTagData.getDefault(routeItem.name)
|
|
|
- }
|
|
|
+ menuTabSate.value = [route.matched[1].name];
|
|
|
systemStore.setStateValue({
|
|
|
key: "menuTabSate",
|
|
|
- value: routeItem.name || "",
|
|
|
+ value: menuTabSate.value[0] || "",
|
|
|
+ localStorage: true,
|
|
|
+ });
|
|
|
+
|
|
|
+ menuSecondSelectedStatusData.value = routesData.find(
|
|
|
+ (item) => item.name == menuTabSate.value
|
|
|
+ );
|
|
|
+ menuSecondData.value = menuSecondSelectedStatusData.value;
|
|
|
+ systemStore.setStateValue({
|
|
|
+ key: "routeItem",
|
|
|
+ value: JSON.stringify(menuSecondData.value),
|
|
|
localStorage: true,
|
|
|
});
|
|
|
};
|
|
@@ -101,35 +149,39 @@ const evGoPage = async (routeItem) => {
|
|
|
watch(
|
|
|
route,
|
|
|
(val) => {
|
|
|
- routesData.forEach(res => {
|
|
|
- if (res.children && res.children.length > 0) {
|
|
|
- res.children.forEach(item => {
|
|
|
- if (item.name == val.name) {
|
|
|
- menuTabSate.value = [res.name]
|
|
|
- routeItemSelectedKeys.value = [item.name]
|
|
|
- menuSecondData.value = res.children
|
|
|
- }
|
|
|
- })
|
|
|
- } else {
|
|
|
- if (res.name == val.name) {
|
|
|
- menuTabSate.value = [res.name]
|
|
|
- menuSecondData.value = []
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
+ if (val.name) {
|
|
|
+ routeItemSelectedKeys.value = [val.name];
|
|
|
+ }
|
|
|
},
|
|
|
{ immediate: true }
|
|
|
);
|
|
|
-
|
|
|
-
|
|
|
</script>
|
|
|
<style scoped lang="less">
|
|
|
-.grid-demo {
|
|
|
- height: 100vh;
|
|
|
- background-color: #fff;
|
|
|
+.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;
|
|
|
}
|
|
|
|
|
|
+.ant-layout-content {
|
|
|
+ height: auto;
|
|
|
+ min-height: auto;
|
|
|
+ overflow-y: auto;
|
|
|
+ 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;
|
|
@@ -139,25 +191,59 @@ watch(
|
|
|
justify-content: center;
|
|
|
|
|
|
.logo {
|
|
|
- width: 36px;
|
|
|
- height: px;
|
|
|
+ width: 100%;
|
|
|
+ height: 32px;
|
|
|
display: flex;
|
|
|
justify-content: center;
|
|
|
align-items: center;
|
|
|
|
|
|
- img {
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
+ h3 {
|
|
|
+ white-space: nowrap;
|
|
|
}
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
+.arco-layout {
|
|
|
+ color: @text_color_1;
|
|
|
+ background: @layout-split-color !important;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
|
|
|
- h3 {
|
|
|
- color: #fff;
|
|
|
- margin-left: 10px;
|
|
|
+:deep(.arco-menu-light) {
|
|
|
+ background-color: @bg_color_3;
|
|
|
+
|
|
|
+ .arco-menu-item {
|
|
|
+ background-color: @bg_color_3;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+:deep(.arco-layout-sider-light) {
|
|
|
+ background-color: @bg_color_3;
|
|
|
+}
|
|
|
+
|
|
|
+:deep(.arco-menu-inline-header) {
|
|
|
+ font-weight: 600;
|
|
|
+ color: @text_color_1;
|
|
|
+ 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 {
|
|
|
+ color: @text_color_1;
|
|
|
+ background-color: @black_3;
|
|
|
+
|
|
|
+ &:after {
|
|
|
+ content: none;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
#layout-sider {
|
|
|
:deep(.arco-menu-selected) {
|
|
@@ -205,4 +291,4 @@ watch(
|
|
|
padding-left: 24px;
|
|
|
}
|
|
|
}
|
|
|
-</style>
|
|
|
+</style>
|