|
|
|
<template>
|
|
|
|
<header
|
|
|
|
class="fixed left-0 right-0 top-0 z-50 w-full bg-transparent"
|
|
|
|
:class="{ 'h-full': isNavbarOpen }"
|
|
|
|
>
|
|
|
|
<div
|
|
|
|
class="max-w-[1920px] mx-auto flex h-17 sm:h-13 w-full items-center justify-between px-28 sm:px-6 md:px-[88px] peer"
|
|
|
|
>
|
|
|
|
<h1 class="font-bold relative z-20">
|
|
|
|
<NuxtLink to="/">
|
|
|
|
<LetterPullup
|
|
|
|
words="BTDK"
|
|
|
|
:delay="0.05"
|
|
|
|
class="text-[#52AC63] text-3xl md:text-2xl sm:text-base"
|
|
|
|
/>
|
|
|
|
</NuxtLink>
|
|
|
|
</h1>
|
|
|
|
<nav class="absolute inset-0">
|
|
|
|
<ul
|
|
|
|
class="flex justify-center text-xl gap-x-4 leading-17 sm:leading-13 text-white sm:hidden md:hidden"
|
|
|
|
>
|
|
|
|
<li
|
|
|
|
v-for="nav in navItems"
|
|
|
|
:key="nav.path"
|
|
|
|
class="w-32 text-center text-inherit cursor-pointer"
|
|
|
|
:class="{ 'group/submenu': !!nav.children?.length }"
|
|
|
|
@click="onNavPush(nav)"
|
|
|
|
>
|
|
|
|
<div
|
|
|
|
class="relative h-full after:absolute after:bottom-0 after:left-0 after:right-0 after:h-1 after:w-full after:origin-top-right after:scale-x-0 after:bg-[#52AC63] after:transition-[transform] after:duration-300 after:content-[''] hover:after:origin-top-left hover:after:scale-x-100"
|
|
|
|
>
|
|
|
|
<span class="text-inherit">
|
|
|
|
{{ nav.name }}
|
|
|
|
</span>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div
|
|
|
|
class="absolute top-17 left-0 right-0 grid grid-rows-[0fr] group-hover/submenu:grid-rows-[1fr] transition-all duration-[400ms]"
|
|
|
|
>
|
|
|
|
<ul
|
|
|
|
class="h-0 overflow-hidden flex justify-center md:flex-col transition-[height] bg-[rgba(18,21,26,.6)] duration-[400ms] backdrop-blur-2xl group-hover/submenu:h-[72px]"
|
|
|
|
>
|
|
|
|
<li
|
|
|
|
v-for="child in nav.children"
|
|
|
|
:key="child.path"
|
|
|
|
class="group/submenuitem mr-[120px] md:mr-[80px] cursor-pointer last:mr-0 text-[hsla(0,0%,100%,.9)]"
|
|
|
|
@click="event => onChildNavPush(child, event)"
|
|
|
|
>
|
|
|
|
<div
|
|
|
|
class="relative h-full after:absolute after:bottom-0 after:left-0 after:right-0 after:h-1 after:w-full after:origin-top-right after:scale-x-0 after:bg-[#52AC63] after:transition-[transform] after:duration-300 after:content-[''] hover:after:origin-top-left hover:after:scale-x-100"
|
|
|
|
>
|
|
|
|
<span class="text-inherit">
|
|
|
|
{{ child.name }}
|
|
|
|
</span>
|
|
|
|
</div>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</div>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</nav>
|
|
|
|
<Menu as="div" class="hidden h-full sm:block md:block" v-slot="{ open: menuOpen }">
|
|
|
|
<MenuButton class="h-full">
|
|
|
|
<div
|
|
|
|
class="navbar-control"
|
|
|
|
:class="{ open: isNavbarOpen }"
|
|
|
|
@click="toggleNavbar(menuOpen)"
|
|
|
|
>
|
|
|
|
<span class="control-icon"></span>
|
|
|
|
<span class="control-icon"></span>
|
|
|
|
<span class="control-icon"></span>
|
|
|
|
</div>
|
|
|
|
</MenuButton>
|
|
|
|
<transition
|
|
|
|
enter-active-class="transition-all duration-300 overflow-hidden"
|
|
|
|
enter-from-class="max-h-0 opacity-70"
|
|
|
|
enter-to-class="h-full opacity-100"
|
|
|
|
leave-active-class="transition-all duration-300 overflow-hidden"
|
|
|
|
leave-from-class="h-full opacity-100"
|
|
|
|
leave-to-class="max-h-0 opacity-70"
|
|
|
|
>
|
|
|
|
<div v-show="isNavbarOpen">
|
|
|
|
<MenuItems
|
|
|
|
as="ul"
|
|
|
|
class="header-bg border-t-1 absolute inset-0 top-17 sm:top-13 z-50 overflow-hidden border-t-[1px] border-[hsla(0,0%,100%,.06)] text-white backdrop-blur-2xl"
|
|
|
|
static
|
|
|
|
>
|
|
|
|
<template v-for="nav in navItems" :key="nav.path">
|
|
|
|
<MenuItem
|
|
|
|
as="li"
|
|
|
|
v-slot="{ close }"
|
|
|
|
class="cursor-pointer text-nowrap text-center text-base md:text-lg"
|
|
|
|
@click="onNavClick(nav, menuOpen)"
|
|
|
|
>
|
|
|
|
<Disclosure as="div" class="size-full" v-slot="{ open }">
|
|
|
|
<DisclosureButton as="p" class="relative py-7">
|
|
|
|
<span>{{ nav.name }} </span>
|
|
|
|
<Icon
|
|
|
|
name="mingcute:up-line"
|
|
|
|
:class="open ? '' : 'rotate-180 transform'"
|
|
|
|
class="absolute right-5 top-1/2 -translate-y-1/2 transition-transform duration-300"
|
|
|
|
:ssr="true"
|
|
|
|
v-if="!!nav.children?.length"
|
|
|
|
/>
|
|
|
|
</DisclosureButton>
|
|
|
|
<transition
|
|
|
|
enter-active-class="transition-all duration-700 overflow-hidden"
|
|
|
|
enter-from-class="max-h-0 opacity-70"
|
|
|
|
enter-to-class="max-h-[300px] opacity-100"
|
|
|
|
leave-active-class="transition-all duration-300 overflow-hidden"
|
|
|
|
leave-from-class="max-h-[300px] opacity-100"
|
|
|
|
leave-to-class="max-h-0 opacity-70"
|
|
|
|
>
|
|
|
|
<DisclosurePanel as="div" v-if="!!nav.children?.length">
|
|
|
|
<ul class="flex flex-col bg-[hsla(0,0%,100%,.06)]">
|
|
|
|
<li
|
|
|
|
class="text-nowrap py-7 text-center"
|
|
|
|
v-for="child in nav.children"
|
|
|
|
:key="child.path"
|
|
|
|
@click="onNavClick(child, menuOpen)"
|
|
|
|
>
|
|
|
|
<span>
|
|
|
|
{{ child.name }}
|
|
|
|
</span>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</DisclosurePanel>
|
|
|
|
</transition>
|
|
|
|
</Disclosure>
|
|
|
|
</MenuItem>
|
|
|
|
</template>
|
|
|
|
</MenuItems>
|
|
|
|
</div>
|
|
|
|
</transition>
|
|
|
|
</Menu>
|
|
|
|
</div>
|
|
|
|
<div
|
|
|
|
class="absolute mx-auto flex sm:h-13 items-center justify-between px-28 sm:px-6 md:px-[88px] h-17 top-0 w-full -z-10 peer-hover:backdrop-blur-2xl peer-hover:bg-[rgba(92,92,92,0.4)] peer-hover:bg-gradient-to-r peer-hover:from-black/50 peer-hover:to-black/50"
|
|
|
|
:class="{
|
|
|
|
'backdrop-blur-2xl': isScrolled || isNavbarOpen,
|
|
|
|
'header-bg': isScrolled,
|
|
|
|
}"
|
|
|
|
></div>
|
|
|
|
</header>
|
|
|
|
<slot />
|
|
|
|
<footer>
|
|
|
|
<div
|
|
|
|
class="relative flex flex-row justify-between sm:justify-center items-center text-sm font-regular bg-[#2D2D2F] md:flex-col p-4 sm:p-2 sm:text-xs"
|
|
|
|
>
|
|
|
|
<div>
|
|
|
|
<!-- <span class="text-[#18AA56] text-[90px] leading-[100px] font-bold">BTDK</span> -->
|
|
|
|
<div
|
|
|
|
class="flex items-center text-sm sm:text-xs text-white opacity-60 pl-2 gap-x-2 sm:flex-col"
|
|
|
|
>
|
|
|
|
<p class="mr-2 lg:mr-0">©比特电科技有限公司</p>
|
|
|
|
<p class="mr-2 flex items-center">
|
|
|
|
<NuxtImg
|
|
|
|
class="size-4 object-cover"
|
|
|
|
loading="lazy"
|
|
|
|
src="/images/commons/beian.jpg"
|
|
|
|
alt="beian"
|
|
|
|
format="webp"
|
|
|
|
/>
|
|
|
|
<a
|
|
|
|
href=" "
|
|
|
|
rel="noreferrer"
|
|
|
|
target="_blank"
|
|
|
|
class="hover:no-underline inline-flex cursor-pointer ml-1"
|
|
|
|
>京公网安备11010802045670号</a
|
|
|
|
>
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</footer>
|
|
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
|
|
import { Menu, MenuButton, MenuItems, MenuItem } from '@headlessui/vue'
|
|
|
|
import { Disclosure, DisclosureButton, DisclosurePanel } from '@headlessui/vue'
|
|
|
|
import LetterPullup from '@/components/ui/letter-pullup/LetterPullup.vue'
|
|
|
|
const isScrolled = ref(false)
|
|
|
|
const router = useRouter()
|
|
|
|
const checkScroll = () => {
|
|
|
|
isScrolled.value = window.scrollY > 20
|
|
|
|
}
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
if (typeof window !== 'undefined') {
|
|
|
|
checkScroll()
|
|
|
|
window.addEventListener('scroll', checkScroll)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
onUnmounted(() => {
|
|
|
|
if (typeof window !== 'undefined') {
|
|
|
|
window.removeEventListener('scroll', checkScroll)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
const isNavbarOpen = ref(false)
|
|
|
|
const toggleNavbar = (open: boolean) => {
|
|
|
|
isNavbarOpen.value = !isNavbarOpen.value
|
|
|
|
}
|
|
|
|
|
|
|
|
const updateStateNavbar = ref(false)
|
|
|
|
|
|
|
|
function onNavPush(nav: any) {
|
|
|
|
if (!!nav.break) {
|
|
|
|
window.open(nav.url, '_blank')
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nav.path) {
|
|
|
|
router.push(nav.path)
|
|
|
|
updateStateNavbar.value = true
|
|
|
|
nextTick(() => {
|
|
|
|
updateStateNavbar.value = false
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function onChildNavPush(child: any, event: Event) {
|
|
|
|
event.stopPropagation()
|
|
|
|
event.preventDefault()
|
|
|
|
|
|
|
|
if (!!child.break) {
|
|
|
|
window.open(child.url, '_blank')
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if (child.path) {
|
|
|
|
router.push(child.path)
|
|
|
|
updateStateNavbar.value = true
|
|
|
|
nextTick(() => {
|
|
|
|
updateStateNavbar.value = false
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function onNavClick(nav: any, menuOpen: boolean) {
|
|
|
|
if (!!nav.children?.length) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
onNavPush(nav)
|
|
|
|
isNavbarOpen.value = false
|
|
|
|
}
|
|
|
|
|
|
|
|
const navItems = [
|
|
|
|
{
|
|
|
|
name: '首页',
|
|
|
|
path: '/',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: '产品中心',
|
|
|
|
path: '',
|
|
|
|
children: [
|
|
|
|
{
|
|
|
|
name: 'BK-1000',
|
|
|
|
path: '/products/BK-1000',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: 'BK-2000',
|
|
|
|
path: '/products/BK-2000',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: '技术资料',
|
|
|
|
path: '',
|
|
|
|
break: true,
|
|
|
|
url: 'http://62.234.18.176:5181/',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: '在线商城',
|
|
|
|
path: '',
|
|
|
|
break: true,
|
|
|
|
url: 'https://3ktcgr18h1x6x7uwnlob22lviaqfk6b.taobao.com',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: '关于我们',
|
|
|
|
path: '/aboutUs',
|
|
|
|
},
|
|
|
|
]
|
|
|
|
</script>
|
|
|
|
<style scoped>
|
|
|
|
.header-bg {
|
|
|
|
@apply bg-[rgba(92,92,92,0.4)] bg-gradient-to-r from-black/50 to-black/50;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 子菜单展开收缩动画 */
|
|
|
|
.transition-all {
|
|
|
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* CSS */
|
|
|
|
.navbar-control {
|
|
|
|
cursor: pointer;
|
|
|
|
height: 100%;
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
gap: 6px;
|
|
|
|
justify-content: center;
|
|
|
|
}
|
|
|
|
|
|
|
|
.control-icon {
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 每个 control-icon 的伪元素 */
|
|
|
|
.control-icon:before {
|
|
|
|
background-color: #fff;
|
|
|
|
border-bottom-left-radius: 1px;
|
|
|
|
border-top-right-radius: 1px;
|
|
|
|
content: '';
|
|
|
|
display: block;
|
|
|
|
height: 1px;
|
|
|
|
transition:
|
|
|
|
transform 0.3s ease 0.2s,
|
|
|
|
background-color 0.3s ease 0s;
|
|
|
|
width: 22px;
|
|
|
|
opacity: 0.9;
|
|
|
|
}
|
|
|
|
.navbar-control.open .control-icon:before {
|
|
|
|
/* background-color: #000; */
|
|
|
|
}
|
|
|
|
.navbar-control.open .control-icon:nth-child(1) {
|
|
|
|
transform: translateY(7px);
|
|
|
|
}
|
|
|
|
.navbar-control.open .control-icon:nth-child(2) {
|
|
|
|
opacity: 0;
|
|
|
|
transition-duration: 0.3s;
|
|
|
|
}
|
|
|
|
|
|
|
|
.navbar-control .control-icon:nth-child(2) {
|
|
|
|
transition-duration: 0.6s;
|
|
|
|
}
|
|
|
|
|
|
|
|
.navbar-control.open .control-icon:nth-child(3) {
|
|
|
|
transform: translateY(-7px);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* open 状态下的动画 */
|
|
|
|
.navbar-control.open .control-icon:nth-child(1):before {
|
|
|
|
transform: rotate(45deg);
|
|
|
|
}
|
|
|
|
.navbar-control.open .control-icon:nth-child(3):before {
|
|
|
|
transform: rotate(-45deg);
|
|
|
|
}
|
|
|
|
</style>
|