feat: 菜单树改为接收值,混合布局下的横向菜单激活、点击横向菜单关联左侧菜单树

This commit is contained in:
wf 2024-05-14 13:05:02 +08:00
parent 122759a525
commit 28db7e85a1
6 changed files with 100 additions and 41 deletions

View File

@ -2,7 +2,7 @@
<div :class="asideDark ? 'aside dark' : 'aside'">
<Logo />
<a-layout-sider :collapsed="collapsed" breakpoint="xl" class="layout_side" :width="220">
<a-scrollbar style="height: 100%; overflow: auto" outer-class="scrollbar"><Menu /></a-scrollbar>
<a-scrollbar style="height: 100%; overflow: auto" outer-class="scrollbar"><Menu :route-tree="routeTree" /></a-scrollbar>
</a-layout-sider>
</div>
</template>
@ -12,9 +12,11 @@ import Logo from "@/layout/components/Logo/index.vue";
import Menu from "@/layout/components/Menu/index.vue";
import { storeToRefs } from "pinia";
import { useThemeConfig } from "@/store/modules/theme-config";
import { useRoutesListStore } from "@/store/modules/route-list";
const themeStore = useThemeConfig();
const { collapsed, asideDark } = storeToRefs(themeStore);
const routerStore = useRoutesListStore();
const { routeTree } = storeToRefs(routerStore);
</script>
<style lang="scss" scoped>

View File

@ -17,7 +17,7 @@
</template>
<script setup lang="ts">
import Breadcrumb from "@/layout/components/Header/components/Breadcrumb/index.vue";
import Breadcrumb from "@/layout/components/Header/components/breadcrumb/index.vue";
import { storeToRefs } from "pinia";
import { useThemeConfig } from "@/store/modules/theme-config";
const themeStore = useThemeConfig();

View File

@ -104,7 +104,7 @@
</template>
<script setup lang="ts">
import Notice from "@/layout/components/Header/components/Notice/index.vue";
import Notice from "@/layout/components/Header/components/notice/index.vue";
import SystemSettings from "@/layout/components/Header/components/system-settings/index.vue";
import ThemeSettings from "@/layout/components/Header/components/theme-settings/index.vue";
import myImage from "@/assets/img/my-image.jpg";

View File

@ -0,0 +1,46 @@
<template>
<a-menu
:breakpoint="layoutType === 'layoutDefaults' ? undefined : 'xl'"
:mode="'vertical'"
:theme="asideDark ? 'dark' : 'light'"
:collapsed="collapsed"
:auto-scroll-into-view="true"
:auto-open-selected="true"
:accordion="isAccordion"
:selected-keys="[currentRoute.name]"
@menu-item-click="onMenuItem"
>
<MenuItem :route-tree="routeTree" />
</a-menu>
</template>
<script setup lang="ts">
import MenuItem from "@/layout/components/Menu/menu-item.vue";
import { storeToRefs } from "pinia";
import { useThemeConfig } from "@/store/modules/theme-config";
import { useRoutesListStore } from "@/store/modules/route-list";
import { useRouter } from "vue-router";
import { useRoutingMethod } from "@/hooks/useRoutingMethod";
const router = useRouter();
const routerStore = useRoutesListStore();
const { routeTree, currentRoute } = storeToRefs(routerStore);
const themeStore = useThemeConfig();
const { collapsed, isAccordion, layoutType, asideDark } = storeToRefs(themeStore);
/**
* @description 菜单点击事件
* @param {String} key
*/
const onMenuItem = (key: string) => {
const { findLinearArray } = useRoutingMethod();
const find = findLinearArray(key);
// 404
if (find) {
router.push(find.path);
} else {
router.push("/404");
}
};
</script>
<style lang="scss" scoped></style>

View File

@ -10,7 +10,7 @@
:selected-keys="[currentRoute.name]"
@menu-item-click="onMenuItem"
>
<MenuItem :route-tree="routeTree" />
<MenuItem :route-tree="props.routeTree" />
</a-menu>
</template>
@ -23,10 +23,19 @@ import { useRouter } from "vue-router";
import { useRoutingMethod } from "@/hooks/useRoutingMethod";
const router = useRouter();
const routerStore = useRoutesListStore();
const { routeTree, currentRoute } = storeToRefs(routerStore);
const { currentRoute } = storeToRefs(routerStore);
const themeStore = useThemeConfig();
const { collapsed, isAccordion, layoutType, asideDark } = storeToRefs(themeStore);
interface Props {
routeTree: Menu.MenuOptions[];
}
// props
// typehttps://cn.vuejs.org/guide/typescript/composition-api.html#typing-component-props
const props = withDefaults(defineProps<Props>(), {
routeTree: () => []
});
/**
* @description 菜单点击事件
* @param {String} key
@ -41,14 +50,6 @@ const onMenuItem = (key: string) => {
router.push("/404");
}
};
// const mode = computed(() => {
// if (layoutType.value === "layoutDefaults") {
// return "vertical";
// } else {
// return "horizontal";
// }
// });
</script>
<style lang="scss" scoped></style>

View File

@ -3,7 +3,7 @@
<div :class="asideDark ? 'aside dark' : 'aside'">
<Logo />
<a-layout-sider :collapsed="collapsed" breakpoint="xl" class="layout_side" :width="220">
<a-scrollbar style="height: 100%; overflow: auto" outer-class="scrollbar"><Menu /></a-scrollbar>
<a-scrollbar style="height: 100%; overflow: auto" outer-class="scrollbar"><Menu :route-tree="routeList" /></a-scrollbar>
</a-layout-sider>
</div>
<a-layout>
@ -19,22 +19,13 @@
</a-button>
</div>
<a-menu mode="horizontal" :selected-keys="[currentRoute.name]" @menu-item-click="onMenuItem">
<template v-for="item in routeTree" :key="item.name">
<a-sub-menu v-if="item.children && item.children.length > 0" :key="item.name">
<template #icon v-if="item.meta.svgIcon || item.meta.icon">
<MenuItemIcon :svg-icon="item.meta.svgIcon" :icon="item.meta.icon" />
</template>
<template #title>{{ $t(`language.${item.meta.title}`) }}</template>
<MenuItem :route-tree="item.children" />
</a-sub-menu>
<a-menu-item v-else :key="item?.name">
<template #icon v-if="item.meta.svgIcon || item.meta.icon">
<MenuItemIcon :svg-icon="item.meta.svgIcon" :icon="item.meta.icon" />
</template>
<span>{{ $t(`language.${item.meta.title}`) }}</span>
</a-menu-item>
</template>
<a-menu mode="horizontal" :selected-keys="[aciveRoute]" @menu-item-click="onMenuItem">
<a-menu-item v-for="item in routeTree" :key="item.name">
<template #icon v-if="item.meta.svgIcon || item.meta.icon">
<MenuItemIcon :svg-icon="item.meta.svgIcon" :icon="item.meta.icon" />
</template>
<span>{{ $t(`language.${item.meta.title}`) }}</span>
</a-menu-item>
</a-menu>
<HeaderRight />
</a-layout-header>
@ -52,7 +43,6 @@ import Main from "@/layout/components/Main/index.vue";
import Footer from "@/layout/components/Footer/index.vue";
import Menu from "@/layout/components/Menu/index.vue";
import HeaderRight from "@/layout/components/Header/components/header-right/index.vue";
import MenuItem from "@/layout/components/Menu/menu-item.vue";
import MenuItemIcon from "@/layout/components/Menu/menu-item-icon.vue";
import { useRouter } from "vue-router";
import { useRoutesListStore } from "@/store/modules/route-list";
@ -60,27 +50,47 @@ import { useRoutingMethod } from "@/hooks/useRoutingMethod";
import { storeToRefs } from "pinia";
import { useThemeConfig } from "@/store/modules/theme-config";
defineOptions({ name: "LayoutMixing" });
const themeStore = useThemeConfig();
const { isFooter, collapsed, asideDark } = storeToRefs(themeStore);
const route = useRoute();
const router = useRouter();
const routerStore = useRoutesListStore();
const { routeTree, currentRoute } = storeToRefs(routerStore);
const themeStore = useThemeConfig();
const { isFooter, collapsed, asideDark } = storeToRefs(themeStore);
const { routeTree } = storeToRefs(routerStore);
//
const onCollapsed = () => {
themeStore.setCollapsed(!collapsed.value);
};
/**
* @description 菜单点击事件
* @param {String} key
*/
console.log("路由信息", route);
//
//
//
const aciveRoute = computed(() => {
if (route.matched.length >= 2) {
return route.matched[1].name;
} else {
return route.matched[0].name;
}
});
//
// children
// children
const routeList = ref<any>([]);
const onMenuItem = (key: string) => {
const { findLinearArray } = useRoutingMethod();
const find = findLinearArray(key);
// 404
if (find) {
// chindren
if (find.children && find.children.length > 0) {
routeList.value = find.children;
} else {
//
routeList.value = [find];
}
router.push(find.path);
} else {
router.push("/404");