navbar.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. <script setup lang="ts">
  2. import Search from "./search/index.vue";
  3. import Notice from "./notice/index.vue";
  4. import mixNav from "./sidebar/mixNav.vue";
  5. import { useNav } from "@/layout/hooks/useNav";
  6. import Breadcrumb from "./sidebar/breadCrumb.vue";
  7. import topCollapse from "./sidebar/topCollapse.vue";
  8. import { useTranslationLang } from "../hooks/useTranslationLang";
  9. import globalization from "@/assets/svg/globalization.svg?component";
  10. import LogoutCircleRLine from "@iconify-icons/ri/logout-circle-r-line";
  11. import Setting from "@iconify-icons/ri/settings-3-line";
  12. import Check from "@iconify-icons/ep/check";
  13. const {
  14. layout,
  15. device,
  16. logout,
  17. onPanel,
  18. pureApp,
  19. username,
  20. avatarsStyle,
  21. toggleSideBar,
  22. getDropdownItemStyle,
  23. getDropdownItemClass
  24. } = useNav();
  25. const { t, locale, translationCh, translationEn } = useTranslationLang();
  26. </script>
  27. <template>
  28. <div
  29. class="navbar bg-[#fff] shadow-sm shadow-[rgba(0, 21, 41, 0.08)] dark:shadow-[#0d0d0d]"
  30. >
  31. <topCollapse
  32. v-if="device === 'mobile'"
  33. class="hamburger-container"
  34. :is-active="pureApp.sidebar.opened"
  35. @toggleClick="toggleSideBar"
  36. />
  37. <Breadcrumb
  38. v-if="layout !== 'mix' && device !== 'mobile'"
  39. class="breadcrumb-container"
  40. />
  41. <mixNav v-if="layout === 'mix'" />
  42. <div v-if="layout === 'vertical'" class="vertical-header-right">
  43. <!-- 菜单搜索 -->
  44. <Search />
  45. <!-- 通知 -->
  46. <Notice id="header-notice" />
  47. <!-- 国际化 -->
  48. <el-dropdown id="header-translation" trigger="click">
  49. <globalization
  50. class="navbar-bg-hover w-[40px] h-[48px] p-[11px] cursor-pointer outline-none"
  51. />
  52. <template #dropdown>
  53. <el-dropdown-menu class="translation">
  54. <el-dropdown-item
  55. :style="getDropdownItemStyle(locale, 'zh')"
  56. :class="['dark:!text-white', getDropdownItemClass(locale, 'zh')]"
  57. @click="translationCh"
  58. >
  59. <IconifyIconOffline
  60. class="check-zh"
  61. v-show="locale === 'zh'"
  62. :icon="Check"
  63. />
  64. 简体中文
  65. </el-dropdown-item>
  66. <el-dropdown-item
  67. :style="getDropdownItemStyle(locale, 'en')"
  68. :class="['dark:!text-white', getDropdownItemClass(locale, 'en')]"
  69. @click="translationEn"
  70. >
  71. <span class="check-en" v-show="locale === 'en'">
  72. <IconifyIconOffline :icon="Check" />
  73. </span>
  74. English
  75. </el-dropdown-item>
  76. </el-dropdown-menu>
  77. </template>
  78. </el-dropdown>
  79. <!-- 退出登录 -->
  80. <el-dropdown trigger="click">
  81. <span class="el-dropdown-link navbar-bg-hover select-none">
  82. <img
  83. src="https://avatars.githubusercontent.com/u/44761321?v=4"
  84. :style="avatarsStyle"
  85. />
  86. <p v-if="username" class="dark:text-white">{{ username }}</p>
  87. </span>
  88. <template #dropdown>
  89. <el-dropdown-menu class="logout">
  90. <el-dropdown-item @click="logout">
  91. <IconifyIconOffline
  92. :icon="LogoutCircleRLine"
  93. style="margin: 5px"
  94. />
  95. {{ t("buttons.hsLoginOut") }}
  96. </el-dropdown-item>
  97. </el-dropdown-menu>
  98. </template>
  99. </el-dropdown>
  100. <span
  101. class="set-icon navbar-bg-hover"
  102. :title="t('buttons.hssystemSet')"
  103. @click="onPanel"
  104. >
  105. <IconifyIconOffline :icon="Setting" />
  106. </span>
  107. </div>
  108. </div>
  109. </template>
  110. <style lang="scss" scoped>
  111. .navbar {
  112. width: 100%;
  113. height: 48px;
  114. overflow: hidden;
  115. .hamburger-container {
  116. float: left;
  117. height: 100%;
  118. line-height: 48px;
  119. cursor: pointer;
  120. }
  121. .vertical-header-right {
  122. display: flex;
  123. align-items: center;
  124. justify-content: flex-end;
  125. min-width: 280px;
  126. height: 48px;
  127. color: #000000d9;
  128. .el-dropdown-link {
  129. display: flex;
  130. align-items: center;
  131. justify-content: space-around;
  132. height: 48px;
  133. padding: 10px;
  134. color: #000000d9;
  135. cursor: pointer;
  136. p {
  137. font-size: 14px;
  138. }
  139. img {
  140. width: 22px;
  141. height: 22px;
  142. border-radius: 50%;
  143. }
  144. }
  145. }
  146. .breadcrumb-container {
  147. float: left;
  148. margin-left: 16px;
  149. }
  150. }
  151. .translation {
  152. ::v-deep(.el-dropdown-menu__item) {
  153. padding: 5px 40px;
  154. }
  155. .check-zh {
  156. position: absolute;
  157. left: 20px;
  158. }
  159. .check-en {
  160. position: absolute;
  161. left: 20px;
  162. }
  163. }
  164. .logout {
  165. max-width: 120px;
  166. ::v-deep(.el-dropdown-menu__item) {
  167. display: inline-flex;
  168. flex-wrap: wrap;
  169. min-width: 100%;
  170. }
  171. }
  172. </style>