|
@@ -0,0 +1,295 @@
|
|
|
+<template>
|
|
|
+ <a-layout style="min-height: 100vh">
|
|
|
+ <a-layout-sider theme="dark" :width="160" :collapsed-width="50" collapsible :trigger="null"
|
|
|
+ @collapse="evMenuSecondLongShow" v-model:collapsed="menuSecondLongShow">
|
|
|
+ <div class="logo-layout">
|
|
|
+ <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>
|
|
|
+ </div>
|
|
|
+ </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)">
|
|
|
+ <template #icon>
|
|
|
+ <svg-icon :icon="routeItem.meta.icon"></svg-icon>
|
|
|
+ </template>
|
|
|
+ <span>{{ routeItem.meta.title }}</span>
|
|
|
+ </a-menu-item>
|
|
|
+ </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 { 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()
|
|
|
+
|
|
|
+ const systemStore = useSystemStore();
|
|
|
+
|
|
|
+ const route = useRoute();
|
|
|
+ const router = useRouter();
|
|
|
+
|
|
|
+ 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",
|
|
|
+ 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) => {
|
|
|
+ if (menuSecondLongShow.value) {
|
|
|
+ menuSecondData.value = routeItem;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 查找最下级
|
|
|
+ const findPath = (data) => {
|
|
|
+ if (data.children && data.children.length > 0) {
|
|
|
+ return findPath(data.children[0]);
|
|
|
+ } else {
|
|
|
+ return 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];
|
|
|
+ systemStore.setStateValue({
|
|
|
+ key: "menuTabSate",
|
|
|
+ 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,
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ watch(
|
|
|
+ route,
|
|
|
+ (val) => {
|
|
|
+ if (val.name) {
|
|
|
+ routeItemSelectedKeys.value = [val.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;
|
|
|
+ }
|
|
|
+
|
|
|
+ .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;
|
|
|
+ color: #fff;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+
|
|
|
+ .logo {
|
|
|
+ width: 100%;
|
|
|
+ height: 32px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ h3 {
|
|
|
+ white-space: nowrap;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .arco-layout {
|
|
|
+ color: @text_color_1;
|
|
|
+ background: @layout-split-color !important;
|
|
|
+ overflow: hidden;
|
|
|
+ }
|
|
|
+
|
|
|
+ :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) {
|
|
|
+ color: @text_color_1 !important;
|
|
|
+ font-weight: bold;
|
|
|
+ background-color: @black_3;
|
|
|
+
|
|
|
+ .arco-icon {
|
|
|
+ color: @text_color_1 !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background-color: rgba(235, 19, 19, 0.1) !important;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep(.arco-menu-inline) {
|
|
|
+ .arco-menu-inline-header {
|
|
|
+ background-color: @bg_color_3;
|
|
|
+ padding-left: 20px;
|
|
|
+ left: 5px;
|
|
|
+
|
|
|
+ svg {
|
|
|
+ color: @text_color_1 !important;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .arco-menu-icon-suffix {
|
|
|
+ color: @text_color_1 !important;
|
|
|
+ left: 0px !important;
|
|
|
+ right: auto;
|
|
|
+ }
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background-color: rgba(255, 255, 255, 0) !important;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .arco-menu-item {
|
|
|
+ padding: 0 5px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep(.arco-menu-item) {
|
|
|
+ padding-left: 24px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ </style>
|