NavHorizontal.vue 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <script setup lang="ts">
  2. import { emitter } from "@/utils/mitt";
  3. import { useNav } from "@/layout/hooks/useNav";
  4. import LaySearch from "../lay-search/index.vue";
  5. import { responsiveStorageNameSpace } from "@/config";
  6. import { ref, nextTick, computed, onMounted } from "vue";
  7. import { storageLocal, isAllEmpty } from "@pureadmin/utils";
  8. import { usePermissionStoreHook } from "@/store/modules/permission";
  9. import LaySidebarItem from "../lay-sidebar/components/SidebarItem.vue";
  10. import LaySidebarFullScreen from "../lay-sidebar/components/SidebarFullScreen.vue";
  11. import LogoutCircleRLine from "~icons/ri/logout-circle-r-line";
  12. import Setting from "~icons/ri/settings-3-line";
  13. const menuRef = ref();
  14. const showLogo = ref(
  15. storageLocal().getItem<StorageConfigs>(
  16. `${responsiveStorageNameSpace()}configure`
  17. )?.showLogo ?? true
  18. );
  19. const {
  20. route,
  21. title,
  22. logout,
  23. onPanel,
  24. getLogo,
  25. username,
  26. userAvatar,
  27. backTopMenu,
  28. avatarsStyle
  29. } = useNav();
  30. const defaultActive = computed(() =>
  31. !isAllEmpty(route.meta?.activePath) ? route.meta.activePath : route.path
  32. );
  33. nextTick(() => {
  34. menuRef.value?.handleResize();
  35. });
  36. onMounted(() => {
  37. emitter.on("logoChange", key => {
  38. showLogo.value = key;
  39. });
  40. });
  41. </script>
  42. <template>
  43. <div
  44. v-loading="usePermissionStoreHook().wholeMenus.length === 0"
  45. class="horizontal-header"
  46. >
  47. <div v-if="showLogo" class="horizontal-header-left" @click="backTopMenu">
  48. <img :src="getLogo()" alt="logo" />
  49. <span>{{ title }}</span>
  50. </div>
  51. <el-menu
  52. ref="menuRef"
  53. mode="horizontal"
  54. popper-class="pure-scrollbar"
  55. class="horizontal-header-menu"
  56. :default-active="defaultActive"
  57. >
  58. <LaySidebarItem
  59. v-for="route in usePermissionStoreHook().wholeMenus"
  60. :key="route.path"
  61. :item="route"
  62. :base-path="route.path"
  63. />
  64. </el-menu>
  65. <div class="horizontal-header-right">
  66. <!-- 菜单搜索 -->
  67. <LaySearch id="header-search" />
  68. <!-- 全屏 -->
  69. <LaySidebarFullScreen id="full-screen" />
  70. <!-- 退出登录 -->
  71. <el-dropdown trigger="click">
  72. <span class="el-dropdown-link navbar-bg-hover">
  73. <img :src="userAvatar" :style="avatarsStyle" />
  74. <p v-if="username" class="dark:text-white">{{ username }}</p>
  75. </span>
  76. <template #dropdown>
  77. <el-dropdown-menu class="logout">
  78. <el-dropdown-item @click="logout">
  79. <IconifyIconOffline
  80. :icon="LogoutCircleRLine"
  81. style="margin: 5px"
  82. />
  83. 退出系统
  84. </el-dropdown-item>
  85. </el-dropdown-menu>
  86. </template>
  87. </el-dropdown>
  88. <span
  89. class="set-icon navbar-bg-hover"
  90. title="打开系统配置"
  91. @click="onPanel"
  92. >
  93. <IconifyIconOffline :icon="Setting" />
  94. </span>
  95. </div>
  96. </div>
  97. </template>
  98. <style lang="scss" scoped>
  99. :deep(.el-loading-mask) {
  100. opacity: 0.45;
  101. }
  102. .logout {
  103. width: 120px;
  104. ::v-deep(.el-dropdown-menu__item) {
  105. display: inline-flex;
  106. flex-wrap: wrap;
  107. min-width: 100%;
  108. }
  109. }
  110. </style>