62 lines
2.4 KiB
Vue
62 lines
2.4 KiB
Vue
<script setup lang="ts">
|
|
import { PhArrowRight as ArrowRight, PhList as List, PhX as X } from '@phosphor-icons/vue'
|
|
|
|
const open = ref(false)
|
|
const toggle = ref<HTMLButtonElement>()
|
|
const navigation = ref<HTMLElement>()
|
|
const props = withDefaults(defineProps<{ logo?: string; brandName?: string; englishName?: string; navFontSize?: number }>(), {
|
|
brandName: '慧遇书院',
|
|
englishName: 'HUIYU ACADEMY',
|
|
navFontSize: 14,
|
|
})
|
|
const route = useRoute()
|
|
const links = computed(() => [
|
|
{ label: '首页', href: '/#home' },
|
|
{ label: `关于${props.brandName}`, href: '/#about' },
|
|
{ label: '卢慧老师', href: '/luhui' },
|
|
{ label: '课程与产品', href: '/products' },
|
|
{ label: '官方信息', href: '/#official' },
|
|
{ label: '品牌动态', href: '/news' },
|
|
{ label: '联系我们', href: '/#contact' },
|
|
])
|
|
|
|
function closeMenu(returnFocus = false) {
|
|
open.value = false
|
|
if (returnFocus) nextTick(() => toggle.value?.focus())
|
|
}
|
|
|
|
function isActive(href: string) {
|
|
if (href.startsWith('/#')) return route.path === '/' && (href === '/#home' || route.hash === href.slice(1))
|
|
return route.path === href || route.path.startsWith(`${href}/`)
|
|
}
|
|
|
|
watch(open, (value) => {
|
|
if (!import.meta.client) return
|
|
document.body.classList.toggle('nav-open', value)
|
|
if (value) nextTick(() => navigation.value?.querySelector<HTMLAnchorElement>('a')?.focus())
|
|
})
|
|
|
|
onBeforeUnmount(() => {
|
|
if (import.meta.client) document.body.classList.remove('nav-open')
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<header class="site-header" :style="{ '--nav-font-size': `${navFontSize}px` }">
|
|
<BrandLogo :src="logo" :name="brandName" :english-name="englishName" />
|
|
<button ref="toggle" class="menu-toggle" type="button" :aria-expanded="open" aria-controls="site-navigation" :aria-label="open ? '关闭导航' : '打开导航'" @click="open = !open" @keydown.esc="closeMenu(true)">
|
|
<X v-if="open" :size="24" />
|
|
<List v-else :size="24" />
|
|
</button>
|
|
<nav id="site-navigation" ref="navigation" :class="['main-nav', { open }]" aria-label="主导航" @keydown.esc="closeMenu(true)">
|
|
<a v-for="link in links" :key="link.href" :href="link.href" :aria-current="isActive(link.href) ? 'page' : undefined" @click="closeMenu()">
|
|
<span class="nav-label">{{ link.label }}</span>
|
|
</a>
|
|
</nav>
|
|
<a class="header-cta" href="/#official">
|
|
官方渠道
|
|
<ArrowRight :size="18" weight="light" />
|
|
</a>
|
|
</header>
|
|
</template>
|