horizontal.vue 5.2 KB

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