|
|
<script setup lang="ts"> import extraIcon from "./extraIcon.vue"; import Search from "../search/index.vue"; import Notice from "../notice/index.vue"; import FullScreen from "./fullScreen.vue"; import { isAllEmpty } from "@pureadmin/utils"; import { useNav } from "@/layout/hooks/useNav"; import { transformI18n } from "@/plugins/i18n"; import { ref, toRaw, watch, onMounted, nextTick } from "vue"; import { useRenderIcon } from "@/components/ReIcon/src/hooks"; import { getParentPaths, findRouteByPath } from "@/router/utils"; import { useTranslationLang } from "../../hooks/useTranslationLang"; import { usePermissionStoreHook } from "@/store/modules/permission"; import globalization from "@/assets/svg/globalization.svg?component"; import LogoutCircleRLine from "@iconify-icons/ri/logout-circle-r-line"; import Setting from "@iconify-icons/ri/settings-3-line"; import Check from "@iconify-icons/ep/check";
const menuRef = ref(); const defaultActive = ref(null);
const { t, route, locale, translationCh, translationEn } = useTranslationLang(menuRef); const { device, logout, onPanel, resolvePath, username, userAvatar, getDivStyle, avatarsStyle, getDropdownItemStyle, getDropdownItemClass } = useNav();
function getDefaultActive(routePath) { const wholeMenus = usePermissionStoreHook().wholeMenus; /** 当前路由的父级路径 */ const parentRoutes = getParentPaths(routePath, wholeMenus)[0]; defaultActive.value = !isAllEmpty(route.meta?.activePath) ? route.meta.activePath : findRouteByPath(parentRoutes, wholeMenus)?.children[0]?.path; }
onMounted(() => { getDefaultActive(route.path); });
nextTick(() => { menuRef.value?.handleResize(); });
watch( () => [route.path, usePermissionStoreHook().wholeMenus], () => { getDefaultActive(route.path); } ); </script>
<template> <div v-if="device !== 'mobile'" v-loading="usePermissionStoreHook().wholeMenus.length === 0" class="horizontal-header" > <el-menu ref="menuRef" router mode="horizontal" popper-class="pure-scrollbar" class="horizontal-header-menu" :default-active="defaultActive" > <el-menu-item v-for="route in usePermissionStoreHook().wholeMenus" :key="route.path" :index="resolvePath(route) || route.redirect" > <template #title> <div v-if="toRaw(route.meta.icon)" :class="['sub-menu-icon', route.meta.icon]" > <component :is="useRenderIcon(route.meta && toRaw(route.meta.icon))" /> </div> <div :style="getDivStyle"> <span class="select-none"> {{ transformI18n(route.meta.title) }} </span> <extraIcon :extraIcon="route.meta.extraIcon" /> </div> </template> </el-menu-item> </el-menu> <div class="horizontal-header-right"> <!-- 菜单搜索 --> <Search id="header-search" /> <!-- 国际化 --> <el-dropdown id="header-translation" trigger="click"> <globalization class="navbar-bg-hover w-[40px] h-[48px] p-[11px] cursor-pointer outline-none" /> <template #dropdown> <el-dropdown-menu class="translation"> <el-dropdown-item :style="getDropdownItemStyle(locale, 'zh')" :class="['dark:!text-white', getDropdownItemClass(locale, 'zh')]" @click="translationCh" > <span v-show="locale === 'zh'" class="check-zh"> <IconifyIconOffline :icon="Check" /> </span> 简体中文 </el-dropdown-item> <el-dropdown-item :style="getDropdownItemStyle(locale, 'en')" :class="['dark:!text-white', getDropdownItemClass(locale, 'en')]" @click="translationEn" > <span v-show="locale === 'en'" class="check-en"> <IconifyIconOffline :icon="Check" /> </span> English </el-dropdown-item> </el-dropdown-menu> </template> </el-dropdown> <!-- 全屏 --> <FullScreen id="full-screen" /> <!-- 消息通知 --> <Notice id="header-notice" /> <!-- 退出登录 --> <el-dropdown trigger="click"> <span class="el-dropdown-link navbar-bg-hover select-none"> <img :src="userAvatar" :style="avatarsStyle" /> <p v-if="username" class="dark:text-white">{{ username }}</p> </span> <template #dropdown> <el-dropdown-menu class="logout"> <el-dropdown-item @click="logout"> <IconifyIconOffline :icon="LogoutCircleRLine" style="margin: 5px" /> {{ t("buttons.pureLoginOut") }} </el-dropdown-item> </el-dropdown-menu> </template> </el-dropdown> <span class="set-icon navbar-bg-hover" :title="t('buttons.pureOpenSystemSet')" @click="onPanel" > <IconifyIconOffline :icon="Setting" /> </span> </div> </div> </template>
<style lang="scss" scoped> :deep(.el-loading-mask) { opacity: 0.45; }
.translation { ::v-deep(.el-dropdown-menu__item) { padding: 5px 40px; }
.check-zh { position: absolute; left: 20px; }
.check-en { position: absolute; left: 20px; } }
.logout { width: 120px;
::v-deep(.el-dropdown-menu__item) { display: inline-flex; flex-wrap: wrap; min-width: 100%; } } </style>
|