HeaderDefault
代码示例
bash
<template>
<nav class="bg-gray-900 shadow fixed top-0 left-0 right-0 z-50">
<div class="max-w-7xl mx-auto px-4">
<div class="flex justify-between h-16">
<div class="flex">
<div class="flex-shrink-0 flex items-center">
<NuxtLink to="/" class="flex items-center">
<img src="xxxxxxxxx.nuxtpro.png" alt="NuxtPro Logo" class="w-12 h-12"/>
<h1 class="ml-2 text-xl font-bold text-white">NuxtPro</h1>
</NuxtLink>
</div>
<div class="hidden sm:ml-6 sm:flex sm:space-x-8">
<NuxtLink
v-for="item in displayMenuItems"
:key="item.path"
:to="item.path"
:class="[
'border-b-2 inline-flex items-center px-1 pt-1 text-sm font-medium transition-all duration-300',
activeMenuItem === (item.path.startsWith('/#') ? item.path.substring(1) : item.path)
? 'border-yellow-400 text-yellow-400'
: 'border-transparent text-gray-300 hover:border-gray-600 hover:text-gray-100'
]"
@click="setActiveMenuItem(item.path)"
>
{{ item.name }}
</NuxtLink>
</div>
</div>
<!-- 修改用户信息区域 -->
<div class="flex items-center space-x-4">
<!-- 移动端汉堡菜单按钮 -->
<button
@click="isMobileMenuOpen = !isMobileMenuOpen"
class="sm:hidden inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-white hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-yellow-400"
>
<span class="sr-only">Open main menu</span>
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path v-if="!isMobileMenuOpen" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
<path v-else stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
<div class="relative" ref="dropdownContainer">
<div class="flex items-center space-x-3">
<span v-if="session.data?.user" class="text-sm text-gray-300 hidden sm:block">{{ session.data?.user.name }}</span>
<button
v-if="session.data?.user"
class="flex text-sm rounded-full focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-900 focus:ring-yellow-400"
@click="toggleDropdown"
>
<img
class="h-8 w-8 rounded-full object-cover"
:src="session.data?.user.image || '/default-avatar.png'"
alt="User avatar"
/>
</button>
<button
v-else
@click="openLoginModal"
class="text-gray-300 hover:text-white font-medium text-sm px-3 py-2 rounded-md hover:bg-gray-700"
>
{{ $t('home.loginButton') }}
</button>
</div>
<!-- 用户下拉菜单 -->
<div v-if="isDropdownOpen && session.data?.user" class="absolute right-0 mt-2 w-48 rounded-md shadow-lg py-1 bg-gray-800 ring-1 ring-black ring-opacity-5">
<div class="px-4 py-2 text-sm text-gray-200 border-b border-gray-700">
<div class="font-medium text-white">{{ session.data?.user.name }}</div>
<div class="text-gray-400">{{ session.data?.user.email }}</div>
</div>
<NuxtLink
to="/affiliate"
class="block w-full text-left px-4 py-2 text-sm text-gray-200 hover:bg-gray-700 hover:text-white"
@click="isDropdownOpen = false"
>
Affiliate
</NuxtLink>
<NuxtLink
to="/customer"
class="block w-full text-left px-4 py-2 text-sm text-gray-200 hover:bg-gray-700 hover:text-white"
@click="isDropdownOpen = false"
>
User Info
</NuxtLink>
<button
@click="handleSignOut"
class="block w-full text-left px-4 py-2 text-sm text-gray-200 hover:bg-gray-700 hover:text-white"
>
Sign Out
</button>
</div>
</div>
<!-- 移动语言切换器到这里 -->
<div class="hidden sm:block border-l border-gray-700 pl-4">
<Select v-model="currentLocale" :options="localeOptions" @update:model-value="switchLanguage">
<SelectTrigger class="w-[120px] bg-gray-800 border-gray-700 text-white hover:bg-gray-700">
<SelectValue :placeholder="$t('common.selectLanguage')" />
</SelectTrigger>
<SelectContent class="bg-gray-800 border-gray-700 text-white">
<SelectItem v-for="locale in localeOptions" :key="locale.value" :value="locale.value" class="hover:bg-gray-700 data-[highlighted]:bg-gray-700 data-[state=checked]:bg-purple-600">
{{ locale.label }}
</SelectItem>
</SelectContent>
</Select>
</div>
</div>
</div>
<!-- Login Modal -->
<div v-if="isLoginModalOpen" class="fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-60 flex items-center justify-center" @click.self="closeLoginModal">
<div class="relative mx-auto p-6 border w-96 shadow-lg rounded-md bg-white">
<button @click="closeLoginModal" class="absolute top-2 right-2 p-1 border border-gray-300 rounded-md hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-400">
<svg class="w-5 h-5 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path></svg>
</button>
<div class="mt-3 text-center">
<div class="flex justify-center items-center mb-4">
<img src="xxxxxxxx.nuxtpro.png" alt="NuxtPro Logo" class="w-8 h-8 mr-2"/>
<h3 class="text-lg leading-6 font-medium text-gray-900">{{ $t('auth.selectLoginMethod') }}</h3>
</div>
<p class="text-sm text-gray-500 mb-4">{{ $t('auth.selectLoginMethodDescription') }}</p>
<div class="mt-2 px-7 py-3 space-y-3">
<button @click="triggerGoogleSignIn" class="w-full flex items-center justify-center px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50">
<img src="xxxxxxx.google.png" alt="Google logo" class="w-5 h-5 mr-2"/>
<span class="ml-2">Sign in with Google</span>
</button>
<button @click="triggerGithubSignIn" class="w-full flex items-center justify-center px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50">
<img src="xxxxxxxx.github.png" alt="GitHub logo" class="w-5 h-5 mr-2"/>
<span class="ml-2">Sign in with Github</span>
</button>
</div>
</div>
</div>
</div>
</nav>
</template>