Files
guanwang/app/components/SiteHeader.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>