139 lines
3.5 KiB
Vue
139 lines
3.5 KiB
Vue
<script setup lang="ts">
|
|
import Logo from "./logo.vue";
|
|
import { useRoute } from "vue-router";
|
|
import { emitter } from "@/utils/mitt";
|
|
import SidebarItem from "./sidebarItem.vue";
|
|
import LeftCollapse from "./leftCollapse.vue";
|
|
import { useNav } from "@/layout/hooks/useNav";
|
|
import CenterCollapse from "./centerCollapse.vue";
|
|
import { responsiveStorageNameSpace } from "@/config";
|
|
import { storageLocal, isAllEmpty } from "@pureadmin/utils";
|
|
import { findRouteByPath, getParentPaths } from "@/router/utils";
|
|
import { usePermissionStoreHook } from "@/store/modules/permission";
|
|
import { ref, computed, watch, onMounted, onBeforeUnmount } from "vue";
|
|
|
|
const route = useRoute();
|
|
const isShow = ref(false);
|
|
const showLogo = ref(
|
|
storageLocal().getItem<StorageConfigs>(
|
|
`${responsiveStorageNameSpace()}configure`
|
|
)?.showLogo ?? true
|
|
);
|
|
|
|
const {
|
|
device,
|
|
pureApp,
|
|
isCollapse,
|
|
tooltipEffect,
|
|
menuSelect,
|
|
toggleSideBar
|
|
} = useNav();
|
|
|
|
const subMenuData = ref([]);
|
|
|
|
const menuData = computed(() => {
|
|
return pureApp.layout === "mix" && device.value !== "mobile"
|
|
? subMenuData.value
|
|
: usePermissionStoreHook().wholeMenus;
|
|
});
|
|
|
|
const loading = computed(() =>
|
|
pureApp.layout === "mix" ? false : menuData.value.length === 0 ? true : false
|
|
);
|
|
|
|
const defaultActive = computed(() =>
|
|
!isAllEmpty(route.meta?.activePath) ? route.meta.activePath : route.path
|
|
);
|
|
|
|
function getSubMenuData() {
|
|
let path = "";
|
|
path = defaultActive.value;
|
|
subMenuData.value = [];
|
|
// path的上级路由组成的数组
|
|
const parentPathArr = getParentPaths(
|
|
path,
|
|
usePermissionStoreHook().wholeMenus
|
|
);
|
|
// 当前路由的父级路由信息
|
|
const parenetRoute = findRouteByPath(
|
|
parentPathArr[0] || path,
|
|
usePermissionStoreHook().wholeMenus
|
|
);
|
|
if (!parenetRoute?.children) return;
|
|
subMenuData.value = parenetRoute?.children;
|
|
}
|
|
|
|
watch(
|
|
() => [route.path, usePermissionStoreHook().wholeMenus],
|
|
() => {
|
|
if (route.path.includes("/redirect")) return;
|
|
getSubMenuData();
|
|
menuSelect(route.path);
|
|
}
|
|
);
|
|
|
|
onMounted(() => {
|
|
getSubMenuData();
|
|
|
|
emitter.on("logoChange", key => {
|
|
showLogo.value = key;
|
|
});
|
|
});
|
|
|
|
onBeforeUnmount(() => {
|
|
// 解绑`logoChange`公共事件,防止多次触发
|
|
emitter.off("logoChange");
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div
|
|
v-loading="loading"
|
|
:class="['sidebar-container', showLogo ? 'has-logo' : 'no-logo']"
|
|
@mouseenter.prevent="isShow = true"
|
|
@mouseleave.prevent="isShow = false"
|
|
>
|
|
<Logo v-if="showLogo" :collapse="isCollapse" />
|
|
<el-scrollbar
|
|
wrap-class="scrollbar-wrapper"
|
|
:class="[device === 'mobile' ? 'mobile' : 'pc']"
|
|
>
|
|
<el-menu
|
|
router
|
|
unique-opened
|
|
mode="vertical"
|
|
popper-class="pure-scrollbar"
|
|
class="outer-most select-none"
|
|
:collapse="isCollapse"
|
|
:collapse-transition="false"
|
|
:popper-effect="tooltipEffect"
|
|
:default-active="defaultActive"
|
|
>
|
|
<sidebar-item
|
|
v-for="routes in menuData"
|
|
:key="routes.path"
|
|
:item="routes"
|
|
:base-path="routes.path"
|
|
class="outer-most select-none"
|
|
/>
|
|
</el-menu>
|
|
</el-scrollbar>
|
|
<CenterCollapse
|
|
v-if="device !== 'mobile' && (isShow || isCollapse)"
|
|
:is-active="pureApp.sidebar.opened"
|
|
@toggleClick="toggleSideBar"
|
|
/>
|
|
<LeftCollapse
|
|
v-if="device !== 'mobile'"
|
|
:is-active="pureApp.sidebar.opened"
|
|
@toggleClick="toggleSideBar"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
:deep(.el-loading-mask) {
|
|
opacity: 0.45;
|
|
}
|
|
</style>
|