120 lines
3.1 KiB
Vue
120 lines
3.1 KiB
Vue
<script setup lang="ts">
|
|
import { ref, watch } from 'vue'
|
|
import { useRoute } from 'vitepress'
|
|
import { Menu, X } from 'lucide-vue-next'
|
|
|
|
interface Props {
|
|
scrolled: boolean
|
|
}
|
|
|
|
defineProps<Props>()
|
|
|
|
const route = useRoute()
|
|
const mobileMenuOpen = ref(false)
|
|
|
|
interface NavItem {
|
|
path: string
|
|
label: string
|
|
}
|
|
|
|
const navItems: NavItem[] = [
|
|
{ path: '/', label: '首页' },
|
|
{ path: '/question-bank', label: '刷题题库' },
|
|
{ path: '/online-school', label: '在线网校' },
|
|
{ path: '/books', label: '出版书籍' },
|
|
{ path: '/knowledge/', label: '知识库' },
|
|
]
|
|
|
|
const handleNavClick = (path: string) => {
|
|
mobileMenuOpen.value = false
|
|
window.scrollTo({ top: 0, behavior: 'smooth' })
|
|
}
|
|
|
|
const isActive = (path: string) => {
|
|
if (path === '/') return route.path === '/'
|
|
return route.path.startsWith(path)
|
|
}
|
|
|
|
watch(() => route.path, () => {
|
|
mobileMenuOpen.value = false
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<header
|
|
:class="[
|
|
'fixed top-0 left-0 right-0 z-50 transition-all duration-300',
|
|
scrolled || mobileMenuOpen
|
|
? 'bg-white/80 backdrop-blur-xl shadow-sm'
|
|
: 'bg-transparent'
|
|
]"
|
|
>
|
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
<div class="flex justify-between items-center h-16">
|
|
<a
|
|
href="/"
|
|
class="flex items-center cursor-pointer group"
|
|
@click="handleNavClick('/')"
|
|
>
|
|
<img
|
|
src="/logo.png"
|
|
alt="恭学教育Logo"
|
|
class="w-8 h-8 mr-2 transition-transform group-hover:scale-105"
|
|
/>
|
|
<span class="font-bold text-lg tracking-tight text-apple-blue">
|
|
恭学教育
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="hidden md:flex space-x-8">
|
|
<a
|
|
v-for="item in navItems"
|
|
:key="item.path"
|
|
:href="item.path"
|
|
:class="[
|
|
'text-sm font-medium transition-colors duration-200',
|
|
isActive(item.path)
|
|
? 'text-apple-blue'
|
|
: 'text-apple-text-gray hover:text-apple-dark'
|
|
]"
|
|
@click="handleNavClick(item.path)"
|
|
>
|
|
{{ item.label }}
|
|
</a>
|
|
</nav>
|
|
|
|
<div class="md:hidden">
|
|
<button
|
|
@click="mobileMenuOpen = !mobileMenuOpen"
|
|
class="text-apple-dark p-2"
|
|
:aria-label="mobileMenuOpen ? '关闭菜单' : '打开菜单'"
|
|
>
|
|
<X v-if="mobileMenuOpen" :size="24" />
|
|
<Menu v-else :size="24" />
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div
|
|
v-if="mobileMenuOpen"
|
|
class="md:hidden absolute top-16 left-0 right-0 bg-white h-screen border-t border-gray-100 p-4 animate-fade-in"
|
|
>
|
|
<div class="flex flex-col space-y-6 mt-4">
|
|
<a
|
|
v-for="item in navItems"
|
|
:key="item.path"
|
|
:href="item.path"
|
|
:class="[
|
|
'text-2xl font-semibold text-left py-2 border-b border-gray-100 w-full',
|
|
isActive(item.path) ? 'text-apple-blue' : 'text-apple-dark'
|
|
]"
|
|
@click="handleNavClick(item.path)"
|
|
>
|
|
{{ item.label }}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
</template>
|