fiee-official-website/src/components/customHeader/size1440/index.vue
2025-08-26 16:27:27 +08:00

259 lines
6.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<!-- 通用页头 -->
<NLayoutHeader
class="custom-header"
:class="{ 'header-scrolled': isScrolled }"
>
<div class="header-container">
<div class="logo" @click="handleToHome">
<NImage width="140" height="140" :src="FiEELogo" preview-disabled />
</div>
<div class="header-menu">
<NConfigProvider :theme-overrides="themeOverrides">
<NMenu
mode="horizontal"
:options="menuOptions"
:inverted="isScrolled"
v-model:value="selectedKey"
@update:value="handleMenuSelect"
/>
</NConfigProvider>
</div>
</div>
</NLayoutHeader>
</template>
<script setup>
import FiEELogo from "@/assets/image/header/logo.png";
import { ref, onMounted, onUnmounted } from "vue";
import { NMenu, NLayoutHeader, NImage, NConfigProvider } from "naive-ui";
import { useI18n } from "vue-i18n";
import { useRouter } from "vue-router";
import { useHeaderMenuConfig } from "@/config/headerMenuConfig";
const themeOverrides = {
Menu: {
// itemTextColor: "#ff7bac", // 默认文本颜色
// 水平模式专用文本颜色(这些才会在水平模式下生效)
// itemTextColorHorizontal: "#ff7bac", // 水平模式默认文本颜色
itemTextColorHoverHorizontal: "#ff7bac", // 水平模式悬停文本颜色
itemTextColorActiveHorizontal: "#ff7bac", // 水平模式激活文本颜色
itemTextColorActiveHoverHorizontal: "#ff7bac", // 水平模式激活悬停文本颜色
itemColorHover: "#ff7bac",
itemColorHoverInverted: "#ff7bac",
},
// 关键:子菜单的悬停背景色在这里配置!
Dropdown: {
optionColorHover: "#fddfea", // 子菜单悬停背景色
optionColorHoverInverted: "#fddfea", // 反转主题下的子菜单悬停背景色
},
};
const { t } = useI18n();
const router = useRouter();
// 使用统一的菜单配置
const menuOptions = useHeaderMenuConfig();
const selectedKey = ref(null);
const isScrolled = ref(false);
// 递归查找菜单项
function findMenuOptionByKey(options, key) {
for (const option of options) {
if (option.key === key) return option;
if (option.children) {
const found = findMenuOptionByKey(option.children, key);
if (found) return found;
}
}
return null;
}
// 菜单点击跳转
const handleMenuSelect = (key) => {
const option = findMenuOptionByKey(menuOptions, key);
if (option && option.href) {
router.push(option.href);
}
};
// 监听滚动事件
const handleScroll = () => {
//滚动距离大于100px时处理对应的header样式
isScrolled.value = window.scrollY >= 100;
};
onMounted(() => {
window.addEventListener("scroll", handleScroll);
});
onUnmounted(() => {
window.removeEventListener("scroll", handleScroll);
});
//点击回到首页
const handleToHome = () => {
router.push("/myhome");
selectedKey.value = null; // 重置菜单选中状态
};
</script>
<style scoped lang="scss">
.custom-header {
--header-height: 5rem;
--primary-color: #8b59f7;
transition: all 0.3s ease;
background: transparent;
height: var(--header-height);
&.header-scrolled {
background: rgba(220, 207, 248, 0.95);
backdrop-filter: blur(8px);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
}
.header-container {
max-width: 1700px;
margin: 0 auto;
padding: 0 40px;
height: 100%;
display: flex;
align-items: center;
justify-content: space-between;
}
.logo {
flex-shrink: 0;
cursor: pointer;
transition: transform 0.3s ease;
margin-left: 100px;
&:hover {
transform: scale(1.05);
}
&:active {
transform: scale(0.98);
}
}
.header-menu {
display: block;
flex: 1;
// :deep(
// .n-menu-item-content:not(.n-menu-item-content--disabled):hover
// .n-menu-item-content-header
// ) {
// color: #ff7bac;
// }
:deep(.n-menu) {
background: transparent;
justify-content: flex-end;
}
:deep(.n-menu-item) {
position: relative;
margin: 0 10px;
transition: all 0.3s ease;
font-weight: 700;
// font-size: 16px;
font-size: 0.875rem;
min-width: 120px;
text-align: center;
&::after {
content: "";
position: absolute;
bottom: 0;
left: 50%;
width: 0;
height: 2px;
background: #ff7bac;
transition: all 0.3s ease;
transform: translateX(-50%);
opacity: 0;
border-radius: 2px;
}
&:hover {
&::after {
width: 80px;
height: 3px;
opacity: 1;
}
}
// 选中状态的样式
&.n-menu-item--selected {
&::after {
width: 40px;
opacity: 1;
}
}
}
// 子菜单样式
:deep(.n-submenu) {
.n-submenu-children {
backdrop-filter: blur(16px);
background: rgba(255, 255, 255, 0.9);
border-radius: 12px;
padding: 8px 0;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
transform-origin: top;
animation: dropDown 0.3s ease;
.n-menu-item {
position: relative;
overflow: hidden;
&::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: var(--primary-color);
transform: translateX(-100%);
transition: transform 0.3s ease;
opacity: 0.1;
z-index: -1;
}
&:hover {
&::before {
transform: translateX(0);
}
}
}
}
}
}
@keyframes dropDown {
from {
opacity: 0;
transform: translateY(-10px) scale(0.95);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
</style>
<style>
.header-menu .n-menu .n-menu-item-content .n-menu-item-content-header {
word-break: break-word;
white-space: unset !important;
}
.header-menu .n-menu .n-submenu .n-menu-item-content {
padding: 0 8px !important;
}
</style>