You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

93 lines
2.5 KiB

  1. <script setup lang="ts">
  2. import Logo from "./logo.vue";
  3. import { useRoute } from "vue-router";
  4. import { emitter } from "@/utils/mitt";
  5. import SidebarItem from "./sidebarItem.vue";
  6. import leftCollapse from "./leftCollapse.vue";
  7. import { useNav } from "@/layout/hooks/useNav";
  8. import { storageLocal } from "@pureadmin/utils";
  9. import { ref, computed, watch, onBeforeMount } from "vue";
  10. import { findRouteByPath, getParentPaths } from "@/router/utils";
  11. import { usePermissionStoreHook } from "@/store/modules/permission";
  12. const route = useRoute();
  13. const showLogo = ref(
  14. storageLocal.getItem<StorageConfigs>("responsive-configure")?.showLogo ?? true
  15. );
  16. const { routers, device, pureApp, isCollapse, menuSelect, toggleSideBar } =
  17. useNav();
  18. const subMenuData = ref([]);
  19. const menuData = computed(() => {
  20. return pureApp.layout === "mix" && device.value !== "mobile"
  21. ? subMenuData.value
  22. : usePermissionStoreHook().wholeMenus;
  23. });
  24. function getSubMenuData(path: string) {
  25. // path的上级路由组成的数组
  26. const parentPathArr = getParentPaths(
  27. path,
  28. usePermissionStoreHook().wholeMenus
  29. );
  30. // 当前路由的父级路由信息
  31. const parenetRoute = findRouteByPath(
  32. parentPathArr[0] || path,
  33. usePermissionStoreHook().wholeMenus
  34. );
  35. if (!parenetRoute?.children) return;
  36. subMenuData.value = parenetRoute?.children;
  37. }
  38. getSubMenuData(route.path);
  39. onBeforeMount(() => {
  40. emitter.on("logoChange", key => {
  41. showLogo.value = key;
  42. });
  43. });
  44. watch(
  45. () => [route.path, usePermissionStoreHook().wholeMenus],
  46. () => {
  47. getSubMenuData(route.path);
  48. menuSelect(route.path, routers);
  49. }
  50. );
  51. </script>
  52. <template>
  53. <div :class="['sidebar-container', showLogo ? 'has-logo' : '']">
  54. <Logo v-if="showLogo" :collapse="isCollapse" />
  55. <el-scrollbar
  56. wrap-class="scrollbar-wrapper"
  57. :class="[device === 'mobile' ? 'mobile' : 'pc']"
  58. >
  59. <el-menu
  60. router
  61. unique-opened
  62. mode="vertical"
  63. class="outer-most select-none"
  64. :collapse="isCollapse"
  65. :default-active="route.path"
  66. :collapse-transition="false"
  67. @select="indexPath => menuSelect(indexPath, routers)"
  68. >
  69. <sidebar-item
  70. v-for="routes in menuData"
  71. :key="routes.path"
  72. :item="routes"
  73. :base-path="routes.path"
  74. class="outer-most select-none"
  75. />
  76. </el-menu>
  77. </el-scrollbar>
  78. <leftCollapse
  79. v-if="device !== 'mobile'"
  80. :is-active="pureApp.sidebar.opened"
  81. @toggleClick="toggleSideBar"
  82. />
  83. </div>
  84. </template>