Files
AIProd/components/Header.vue

237 lines
5.0 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>
<div id="header-container">
<IntegratedLayout>
<div class="navigation-container">
<div class="logo">
<img src="/logo/white-logo.png" alt="" />
<span>AIProdLaunch</span>
</div>
<div class="flex">
<div class="navigation-item pointer" v-for="item in navRoutes" :key="item.path"
@click="handleParentClick(item)" @mouseenter="showSubmenu(item)" @mouseleave="hideSubmenu">
<span
:class="{ 'selected-navigation': isParentMatch(item) }">{{item.meta.navigationName }}
<i class="el-icon-arrow-down" v-if="item.meta.children"></i>
</span>
<div v-if="activeMenu === item.path && item.meta.children" class="submenu">
<div v-for="sub in item.children" :key="sub.path" @click.stop="goto(sub.path)"
class="submenu-item pointer">
<div class="wh-24 flex-center mr-10" :style="{ background: sub.meta.color }">
<img :src="`/menu/${sub.meta.icon}.png`" alt="" />
</div>
{{ sub.name }}
<!-- 添加真实的DOM元素作为背景动画 -->
<div class="submenu-item-bg" :style="{ backgroundColor: sub.meta.color || '#f1f5f9' }"></div>
</div>
</div>
</div>
</div>
</div>
</IntegratedLayout>
</div>
</template>
<script>
import {
routes
} from '~/router';
export default {
name: "Header",
computed: {
/**
* 得到routes的meta里非hidden的路由
*/
navRoutes() {
const r = routes.filter(e => {
if (e.meta) {
return !e.meta.hidden
}
return false
})
return r
},
/**
* 得到当前的路由path
*/
currentRoutePath() {
return this.$route.path
}
},
data() {
return {
activeMenu: null
}
},
methods: {
handleParentClick(item) {
const hasVisibleChildren = item.meta && !item.meta.children;
if (hasVisibleChildren) {
this.goto(item.path);
}
},
/**
* 编程式导航
* @param {String} path 导航的路径
*/
goto(path) {
this.$router.push(path)
},
showSubmenu(item) {
if (item.children) {
this.activeMenu = item.path;
}
},
hideSubmenu() {
this.activeMenu = null;
},
/**
* 判断当前导航项是否应该被选中
* @param {Object} item 导航项
* @returns {Boolean} 是否选中
*/
isParentMatch(item) {
// 首先检查原始的路径匹配逻辑,保持向后兼容性
const pathMatch = this.$route.matched.some(record => record.path === item.path);
if (pathMatch) return true;
// 获取当前路由的meta信息
const currentRouteMeta = this.$route.meta || {};
const currentParent = currentRouteMeta.parent;
// 如果当前路由没有parent属性直接返回false
if (!currentParent) return false;
// 获取当前导航项的meta信息
const navItemMeta = item.meta || {};
const navItemParent = navItemMeta.parent || '';
// 根据parent属性的类型进行判断
if (typeof currentParent === 'string') {
// parent是字符串时直接比较是否相等
return currentParent === navItemParent;
} else if (Array.isArray(currentParent)) {
// parent是数组时判断导航项的parent是否在数组中
return currentParent.includes(navItemParent);
}
// 其他情况返回false
return false;
}
}
};
</script>
<style lang="scss" scoped>
.mr-10 {
margin-right: 10px;
}
#header-container {
width: 100%;
background: $header-backgroungd;
height: 72px;
.navigation-container {
height: $navigationBarHeight;
display: flex;
align-items: center;
justify-content: space-between;
.logo {
@include flex-center;
color: $white;
font-family: 'Poppins-Bold';
span {
font-size: $normal-font-size;
}
}
.navigation-item {
margin-left: 20px;
padding: 10px;
position: relative;
font-family: 'Poppins-Medium';
span {
color: $grey;
&:hover {
color: $white;
}
&.selected-navigation {
color: $white;
font-family: 'Poppins-Bold';
}
}
.submenu {
z-index: 10;
position: absolute;
top: 100%;
padding: 20px 10px;
background: $white;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
border-radius: 6px;
.submenu-item {
white-space: nowrap;
padding: 8px;
color: #1e293b;
@include display-flex;
font-size: 18px;
position: relative;
overflow: hidden;
z-index: 1;
margin-bottom: 16px;
img {
width: 24px;
height: 24px;
transition: transform 0.3s ease;
}
// 鼠标悬停效果
&:hover {
cursor: pointer;
img {
transform: scale(1.1); // 放大图片到1.1倍
}
.submenu-item-bg {
left: 0;
}
}
// 真实的DOM元素作为背景动画
.submenu-item-bg {
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
z-index: -1;
transition: left 0.3s ease;
}
&:last-child {
margin-bottom: 0;
}
}
}
}
}
}
@keyframes slideIn {
from {
left: -100%;
}
to {
left: 0;
}
}
</style>