|
@@ -0,0 +1,161 @@
|
|
|
|
+<template>
|
|
|
|
+ <div class="side-wp">
|
|
|
|
+ <div class="menu_switch_wp" @click="handeCwitchCollapse()">
|
|
|
|
+ <lay-icon size="12px" :type="collapse ? 'layui-icon-right' : 'layui-icon-left'" />
|
|
|
|
+ </div>
|
|
|
|
+ <lay-menu class="menu-wp" :selected-key="selectedKey" theme="light" v-model:openKeys="openKeys" :collapse="collapse" :tree="true">
|
|
|
|
+ <template v-for="item in list">
|
|
|
|
+ <lay-menu-item :id="item.path" v-if="item.childMenu.length == 0" @click="jumpPage(item)">
|
|
|
|
+ <template #icon>
|
|
|
|
+ <lay-icon :type="item.icon" />
|
|
|
|
+ </template>
|
|
|
|
+ <template #title>
|
|
|
|
+ {{ item.name }}
|
|
|
|
+ </template>
|
|
|
|
+ </lay-menu-item>
|
|
|
|
+ <lay-sub-menu :id="item.path" v-else>
|
|
|
|
+ <template #icon>
|
|
|
|
+ <lay-icon :type="item.icon" />
|
|
|
|
+ </template>
|
|
|
|
+ <template #title>
|
|
|
|
+ {{ item.name }}
|
|
|
|
+ </template>
|
|
|
|
+ <lay-menu-item :id="items.path" v-for="items in item.childMenu" @click="jumpPage(items)">
|
|
|
|
+ <span class="child-menu">{{ items.name }}</span>
|
|
|
|
+ </lay-menu-item>
|
|
|
|
+ </lay-sub-menu>
|
|
|
|
+ </template>
|
|
|
|
+ </lay-menu>
|
|
|
|
+ </div>
|
|
|
|
+</template>
|
|
|
|
+
|
|
|
|
+<script lang="ts" setup>
|
|
|
|
+import { ref, watchEffect } from "vue";
|
|
|
|
+import { useRouter, useRoute } from "vue-router";
|
|
|
|
+
|
|
|
|
+const emit = defineEmits(["collapse", "open"]);
|
|
|
|
+
|
|
|
|
+const router = useRouter();
|
|
|
|
+const route = useRoute();
|
|
|
|
+
|
|
|
|
+interface MenuList {
|
|
|
|
+ icon?: string;
|
|
|
|
+ id?: number;
|
|
|
|
+ name?: string;
|
|
|
|
+ parentId?: number;
|
|
|
|
+ path?: string;
|
|
|
|
+ type?: number;
|
|
|
|
+ childMenu: Array<MenuList>;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const openKeys = ref<Array<string>>([]);
|
|
|
|
+const selectedKey = ref();
|
|
|
|
+const collapse = ref<boolean>(JSON.parse(window.sessionStorage.getItem("_4L_MENU_COLLAPSE") || "false"));
|
|
|
|
+
|
|
|
|
+const prpos = defineProps({
|
|
|
|
+ list: Array<MenuList>,
|
|
|
|
+ keepAliveList: Array<any>,
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+watchEffect(() => {
|
|
|
|
+ selectedKey.value = route.fullPath;
|
|
|
|
+ openKeys.value = [`/${route.fullPath.split("/")[1]}`];
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+const handeCwitchCollapse = () => {
|
|
|
|
+ collapse.value = !collapse.value;
|
|
|
|
+ window.sessionStorage.setItem("_4L_MENU_COLLAPSE", JSON.stringify(collapse.value));
|
|
|
|
+ emit("collapse", collapse.value);
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const setSelectedKey = () => {
|
|
|
|
+ const defaultMenu = JSON.parse(window.sessionStorage.getItem("_4L_MENU_PATH") || "{}");
|
|
|
|
+ const selectedMenu = JSON.parse(window.sessionStorage.getItem("_4L_S_MENU_PATH") || "{}");
|
|
|
|
+ if (Object.keys(selectedMenu).length > 0) {
|
|
|
|
+ selectedKey.value = selectedMenu.path;
|
|
|
|
+ openKeys.value = [`/${selectedMenu.path.split("/")[1]}`];
|
|
|
|
+ jumpPage(selectedMenu);
|
|
|
|
+ } else if (Object.keys(defaultMenu).length > 0) {
|
|
|
|
+ selectedKey.value = defaultMenu.path;
|
|
|
|
+ openKeys.value = [`/${defaultMenu.path.split("/")[1]}`];
|
|
|
|
+ jumpPage(defaultMenu);
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const jumpPage = (menu: any) => {
|
|
|
|
+ router.push({ path: menu.path, query: menu.query });
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ if (route.meta.keepAlive && !prpos.keepAliveList!.includes(route.name)) {
|
|
|
|
+ emit("open", route.name);
|
|
|
|
+ }
|
|
|
|
+ }, 100);
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+setSelectedKey();
|
|
|
|
+
|
|
|
|
+defineExpose({ collapse });
|
|
|
|
+</script>
|
|
|
|
+<style lang="scss" scoped>
|
|
|
|
+.side-wp {
|
|
|
|
+ position: relative;
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
+ height: 100%;
|
|
|
|
+ width: 100%;
|
|
|
|
+ border-right: 1px solid rgba(0, 0, 0, 0.1);
|
|
|
|
+ .menu_switch_wp {
|
|
|
|
+ position: absolute;
|
|
|
|
+ right: -12px;
|
|
|
|
+ top: 40px;
|
|
|
|
+ width: 24px;
|
|
|
|
+ height: 24px;
|
|
|
|
+ font-size: 0;
|
|
|
|
+ line-height: 24px;
|
|
|
|
+ background: #ffffff;
|
|
|
|
+ color: rgba(51, 51, 51, 0.25);
|
|
|
|
+ text-align: center;
|
|
|
|
+ border-radius: 50%;
|
|
|
|
+ z-index: 2;
|
|
|
|
+ box-shadow: 0 2px 8px -2px rgba(0, 0, 0, 0.05), 0 1px 4px -1px rgba(25, 15, 15, 0.07), 0 0 1px 0 rgba(0, 0, 0, 0.08);
|
|
|
|
+ &:hover {
|
|
|
|
+ color: rgba(51, 51, 51, 1);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ .menu-wp {
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
+ padding: 0;
|
|
|
|
+ width: auto;
|
|
|
|
+ }
|
|
|
|
+ :deep(.layui-nav-tree) {
|
|
|
|
+ .layui-this {
|
|
|
|
+ position: relative;
|
|
|
|
+ a {
|
|
|
|
+ background-color: rgb(232, 252, 247) !important;
|
|
|
|
+ border-right: 2px solid var(--color-theme) !important;
|
|
|
|
+ &::after {
|
|
|
|
+ content: "";
|
|
|
|
+ position: absolute;
|
|
|
|
+ width: 8px;
|
|
|
|
+ height: 8px;
|
|
|
|
+ z-index: 1;
|
|
|
|
+ transform: rotate(45deg) translateY(-50%);
|
|
|
|
+ transform-origin: center;
|
|
|
|
+ border-top: 1px solid var(--color-theme) !important;
|
|
|
|
+ border-right: 1px solid var(--color-theme) !important;
|
|
|
|
+ right: 20px;
|
|
|
|
+ top: 50%;
|
|
|
|
+ }
|
|
|
|
+ span,
|
|
|
|
+ i {
|
|
|
|
+ color: var(--color-theme) !important;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ .layui-nav-child {
|
|
|
|
+ padding: 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ .child-menu {
|
|
|
|
+ padding-left: 14px;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+</style>
|