vertical.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  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 CenterCollapse from "./centerCollapse.vue";
  9. import { responsiveStorageNameSpace } from "@/config";
  10. import { storageLocal, isAllEmpty } from "@pureadmin/utils";
  11. import { findRouteByPath, getParentPaths } from "@/router/utils";
  12. import { usePermissionStoreHook } from "@/store/modules/permission";
  13. import { ref, computed, watch, onMounted, onBeforeUnmount } from "vue";
  14. import bg from "@/assets/login/one/bg.png";
  15. const route = useRoute();
  16. const isShow = ref(false);
  17. const showLogo = ref(
  18. storageLocal().getItem<StorageConfigs>(
  19. `${responsiveStorageNameSpace()}configure`
  20. )?.showLogo ?? true
  21. );
  22. const {
  23. device,
  24. pureApp,
  25. isCollapse,
  26. tooltipEffect,
  27. menuSelect,
  28. toggleSideBar
  29. } = useNav();
  30. const subMenuData = ref([]);
  31. const menuData = computed(() => {
  32. return pureApp.layout === "mix" && device.value !== "mobile"
  33. ? subMenuData.value
  34. : usePermissionStoreHook().wholeMenus;
  35. });
  36. const loading = computed(() =>
  37. pureApp.layout === "mix" ? false : menuData.value.length === 0 ? true : false
  38. );
  39. const defaultActive = computed(() =>
  40. !isAllEmpty(route.meta?.activePath) ? route.meta.activePath : route.path
  41. );
  42. function getSubMenuData() {
  43. let path = "";
  44. path = defaultActive.value;
  45. subMenuData.value = [];
  46. // path的上级路由组成的数组
  47. const parentPathArr = getParentPaths(
  48. path,
  49. usePermissionStoreHook().wholeMenus
  50. );
  51. // 当前路由的父级路由信息
  52. const parenetRoute = findRouteByPath(
  53. parentPathArr[0] || path,
  54. usePermissionStoreHook().wholeMenus
  55. );
  56. if (!parenetRoute?.children) return;
  57. subMenuData.value = parenetRoute?.children;
  58. }
  59. watch(
  60. () => [route.path, usePermissionStoreHook().wholeMenus],
  61. () => {
  62. if (route.path.includes("/redirect")) return;
  63. getSubMenuData();
  64. menuSelect(route.path);
  65. }
  66. );
  67. onMounted(() => {
  68. getSubMenuData();
  69. emitter.on("logoChange", key => {
  70. showLogo.value = key;
  71. });
  72. });
  73. onBeforeUnmount(() => {
  74. // 解绑`logoChange`公共事件,防止多次触发
  75. emitter.off("logoChange");
  76. });
  77. </script>
  78. <template>
  79. <div>
  80. <div
  81. v-loading="loading"
  82. :class="['sidebar-container', showLogo ? 'has-logo' : 'no-logo']"
  83. @mouseenter.prevent="isShow = true"
  84. @mouseleave.prevent="isShow = false"
  85. >
  86. <Logo v-if="showLogo" :collapse="isCollapse" />
  87. <el-scrollbar
  88. wrap-class="scrollbar-wrapper"
  89. :class="[
  90. device === 'mobile' ? 'mobile' : 'pc',
  91. route.name === 'Welcome' ? '' : 'bottomRR'
  92. ]"
  93. style="background-color: #d5e8fb"
  94. >
  95. <el-menu
  96. router
  97. unique-opened
  98. mode="vertical"
  99. popper-class="pure-scrollbar"
  100. class="outer-most select-none"
  101. :collapse="isCollapse"
  102. :collapse-transition="false"
  103. :popper-effect="tooltipEffect"
  104. :default-active="defaultActive"
  105. >
  106. <sidebar-item
  107. v-for="routes in menuData"
  108. :key="routes.path"
  109. :item="routes"
  110. :base-path="routes.path"
  111. class="outer-most select-none"
  112. />
  113. </el-menu>
  114. </el-scrollbar>
  115. <div
  116. v-if="
  117. ![
  118. 'Welcome',
  119. 'evaluateNewAdd',
  120. 'workerDataDetail',
  121. 'departmentDataDetail',
  122. 'headDataDetail',
  123. 'healthDataDetail'
  124. ].includes(route.name)
  125. "
  126. >
  127. <CenterCollapse
  128. v-if="device !== 'mobile' && (isShow || isCollapse)"
  129. :is-active="pureApp.sidebar.opened"
  130. @toggleClick="toggleSideBar"
  131. />
  132. </div>
  133. <LeftCollapse
  134. v-if="device !== 'mobile'"
  135. :is-active="pureApp.sidebar.opened"
  136. style="background-color: #d5e8fb"
  137. @toggleClick="toggleSideBar"
  138. />
  139. </div>
  140. <img
  141. v-if="route.name == 'Welcome'"
  142. class="bg absolute bottom-0 right-0"
  143. :src="bg"
  144. alt=""
  145. />
  146. </div>
  147. </template>
  148. <style scoped>
  149. .bg {
  150. /* border: 1px solid red; */
  151. left: 0;
  152. z-index: 9999;
  153. width: 500px !important;
  154. height: 500px;
  155. margin-bottom: 20px;
  156. }
  157. :deep(.el-loading-mask) {
  158. opacity: 0.45;
  159. }
  160. .bottomRR {
  161. border-top-left-radius: 15px !important;
  162. /* border: 1px solid red; */
  163. }
  164. </style>