horizontal.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. <script setup lang="ts">
  2. import {
  3. computed,
  4. unref,
  5. watch,
  6. nextTick,
  7. onMounted,
  8. getCurrentInstance
  9. } from "vue";
  10. import { useI18n } from "vue-i18n";
  11. import { emitter } from "/@/utils/mitt";
  12. import Notice from "../notice/index.vue";
  13. import { templateRef } from "@vueuse/core";
  14. import SidebarItem from "./sidebarItem.vue";
  15. import { algorithm } from "/@/utils/algorithm";
  16. import screenfull from "../screenfull/index.vue";
  17. import { useRoute, useRouter } from "vue-router";
  18. import { storageSession } from "/@/utils/storage";
  19. import Icon from "/@/components/ReIcon/src/Icon.vue";
  20. import { deviceDetection } from "/@/utils/deviceDetection";
  21. import globalization from "/@/assets/svg/globalization.svg";
  22. import { usePermissionStoreHook } from "/@/store/modules/permission";
  23. const instance =
  24. getCurrentInstance().appContext.config.globalProperties.$storage;
  25. const title =
  26. getCurrentInstance().appContext.config.globalProperties.$config?.Title;
  27. const menuRef = templateRef<ElRef | null>("menu", null);
  28. const routeStore = usePermissionStoreHook();
  29. const route = useRoute();
  30. const router = useRouter();
  31. const routers = useRouter().options.routes;
  32. let usename = storageSession.getItem("info")?.username;
  33. const { locale, t } = useI18n();
  34. watch(
  35. () => locale.value,
  36. () => {
  37. //@ts-ignore
  38. // 动态title
  39. document.title = t(unref(route.meta.title));
  40. }
  41. );
  42. // 退出登录
  43. const logout = (): void => {
  44. storageSession.removeItem("info");
  45. router.push("/login");
  46. };
  47. function onPanel() {
  48. emitter.emit("openPanel");
  49. }
  50. const activeMenu = computed((): string => {
  51. const { meta, path } = route;
  52. if (meta.activeMenu) {
  53. // @ts-ignore
  54. return meta.activeMenu;
  55. }
  56. return path;
  57. });
  58. const menuSelect = (indexPath: string): void => {
  59. let parentPath = "";
  60. let parentPathIndex = indexPath.lastIndexOf("/");
  61. if (parentPathIndex > 0) {
  62. parentPath = indexPath.slice(0, parentPathIndex);
  63. }
  64. // 找到当前路由的信息
  65. function findCurrentRoute(routes) {
  66. return routes.map(item => {
  67. if (item.path === indexPath) {
  68. // 切换左侧菜单 通知标签页
  69. emitter.emit("changLayoutRoute", {
  70. indexPath,
  71. parentPath
  72. });
  73. } else {
  74. if (item.children) findCurrentRoute(item.children);
  75. }
  76. });
  77. }
  78. findCurrentRoute(algorithm.increaseIndexes(routers));
  79. };
  80. function backHome() {
  81. router.push("/welcome");
  82. }
  83. function handleResize() {
  84. // @ts-ignore
  85. menuRef.value.handleResize();
  86. }
  87. // 简体中文
  88. function translationCh() {
  89. instance.locale = { locale: "zh" };
  90. locale.value = "zh";
  91. handleResize();
  92. }
  93. // English
  94. function translationEn() {
  95. instance.locale = { locale: "en" };
  96. locale.value = "en";
  97. handleResize();
  98. }
  99. onMounted(() => {
  100. nextTick(() => {
  101. handleResize();
  102. });
  103. });
  104. </script>
  105. <template>
  106. <div class="horizontal-header">
  107. <div class="horizontal-header-left" @click="backHome">
  108. <Icon svg :width="35" :height="35" content="team-iconlogo" />
  109. <h4>{{ title }}</h4>
  110. </div>
  111. <el-menu
  112. ref="menu"
  113. :default-active="activeMenu"
  114. unique-opened
  115. router
  116. class="horizontal-header-menu"
  117. mode="horizontal"
  118. @select="menuSelect"
  119. >
  120. <sidebar-item
  121. v-for="route in routeStore.wholeRoutes"
  122. :key="route.path"
  123. :item="route"
  124. :base-path="route.path"
  125. />
  126. </el-menu>
  127. <div class="horizontal-header-right">
  128. <!-- 通知 -->
  129. <Notice />
  130. <!-- 全屏 -->
  131. <screenfull v-show="!deviceDetection()" />
  132. <!-- 国际化 -->
  133. <el-dropdown trigger="click">
  134. <globalization />
  135. <template #dropdown>
  136. <el-dropdown-menu class="translation">
  137. <el-dropdown-item
  138. :style="{
  139. background: locale === 'zh' ? '#1b2a47' : '',
  140. color: locale === 'zh' ? '#f4f4f5' : '#000'
  141. }"
  142. @click="translationCh"
  143. ><el-icon class="check-zh" v-show="locale === 'zh'"
  144. ><check /></el-icon
  145. >简体中文</el-dropdown-item
  146. >
  147. <el-dropdown-item
  148. :style="{
  149. background: locale === 'en' ? '#1b2a47' : '',
  150. color: locale === 'en' ? '#f4f4f5' : '#000'
  151. }"
  152. @click="translationEn"
  153. ><el-icon class="check-en" v-show="locale === 'en'"
  154. ><check /></el-icon
  155. >English</el-dropdown-item
  156. >
  157. </el-dropdown-menu>
  158. </template>
  159. </el-dropdown>
  160. <!-- 退出登陆 -->
  161. <el-dropdown trigger="click">
  162. <span class="el-dropdown-link">
  163. <img
  164. src="https://avatars.githubusercontent.com/u/44761321?s=400&u=30907819abd29bb3779bc247910873e7c7f7c12f&v=4"
  165. />
  166. <p>{{ usename }}</p>
  167. </span>
  168. <template #dropdown>
  169. <el-dropdown-menu class="logout">
  170. <el-dropdown-item icon="el-icon-switch-button" @click="logout">{{
  171. $t("message.hsLoginOut")
  172. }}</el-dropdown-item>
  173. </el-dropdown-menu>
  174. </template>
  175. </el-dropdown>
  176. <el-icon
  177. class="el-icon-setting"
  178. :title="$t('message.hssystemSet')"
  179. @click="onPanel"
  180. >
  181. <Setting />
  182. </el-icon>
  183. </div>
  184. </div>
  185. </template>
  186. <style lang="scss" scoped>
  187. .translation {
  188. .el-dropdown-menu__item {
  189. padding: 0 40px !important;
  190. }
  191. .el-dropdown-menu__item:focus,
  192. .el-dropdown-menu__item:not(.is-disabled):hover {
  193. color: #606266;
  194. background: #f0f0f0;
  195. }
  196. .check-zh {
  197. position: absolute;
  198. left: 20px;
  199. top: 13px;
  200. }
  201. .check-en {
  202. position: absolute;
  203. bottom: 13px;
  204. left: 20px;
  205. }
  206. }
  207. .logout {
  208. .el-dropdown-menu__item {
  209. padding: 0 18px !important;
  210. }
  211. .el-dropdown-menu__item:focus,
  212. .el-dropdown-menu__item:not(.is-disabled):hover {
  213. color: #606266;
  214. background: #f0f0f0;
  215. }
  216. }
  217. </style>