162 lines
4.0 KiB
Vue
162 lines
4.0 KiB
Vue
|
<script lang="ts" setup>
|
||
|
import {computed, onMounted, onUnmounted, ref} from "vue";
|
||
|
|
||
|
type Widget = {
|
||
|
icon: string[]
|
||
|
url: string
|
||
|
title: string
|
||
|
}
|
||
|
|
||
|
// 使用 ref 跟踪是否滚动
|
||
|
const scrolled = ref(false)
|
||
|
const littleWidget: Widget[] = [
|
||
|
{
|
||
|
icon: ['fas', 'gauge'],
|
||
|
url: "/netdata/",
|
||
|
title: "Pi Dashboard",
|
||
|
},
|
||
|
{
|
||
|
icon: ['fas', 'cloud'],
|
||
|
url: "/nas/",
|
||
|
title: "Nextcloud",
|
||
|
},
|
||
|
{
|
||
|
icon: ['fas', 'code-branch'],
|
||
|
url: "/git/",
|
||
|
title: "Git Repository"
|
||
|
}
|
||
|
]
|
||
|
//const logoUrl = getAssetURL("w.png")
|
||
|
const logoType: string = "logo";
|
||
|
const showLogo = computed(() => logoType === 'text')
|
||
|
const isExpended = ref<boolean>(false)
|
||
|
const route = useRoute()
|
||
|
|
||
|
const entry = [
|
||
|
{
|
||
|
title: '主页',
|
||
|
icon: ['fas', 'home'],
|
||
|
entry: [],
|
||
|
to: 'home'
|
||
|
},
|
||
|
{
|
||
|
title: '文章',
|
||
|
icon: ['fas', 'pen'],
|
||
|
entry: [
|
||
|
{
|
||
|
title: '博客',
|
||
|
url: false,
|
||
|
to: 'blog'
|
||
|
},
|
||
|
{
|
||
|
title: '日记',
|
||
|
url: false,
|
||
|
to: 'diary'
|
||
|
},
|
||
|
],
|
||
|
},
|
||
|
{
|
||
|
title: '作品',
|
||
|
icon: ['fas', 'brush'],
|
||
|
entry: [
|
||
|
{
|
||
|
title: '软件',
|
||
|
url: false,
|
||
|
to: 'soft'
|
||
|
},
|
||
|
{
|
||
|
title: '仓库',
|
||
|
url: true,
|
||
|
to: 'https://cantyonion.site/git/'
|
||
|
},
|
||
|
],
|
||
|
},
|
||
|
{
|
||
|
title: '杂谈',
|
||
|
icon: ['fas', 'chess-rook'],
|
||
|
entry: [],
|
||
|
to: 'talk'
|
||
|
}
|
||
|
]
|
||
|
|
||
|
const menuExpanded = () => {
|
||
|
isExpended.value = !isExpended.value
|
||
|
}
|
||
|
|
||
|
const menuClose = () => {
|
||
|
isExpended.value = false
|
||
|
}
|
||
|
|
||
|
// 监听 scroll 事件
|
||
|
const handleScroll = () => {
|
||
|
scrolled.value = window.scrollY > 0
|
||
|
}
|
||
|
|
||
|
const debouncedScroll = debounce(handleScroll, 10)
|
||
|
|
||
|
const alwaysBlueBackground = computed(() => route.name !== 'index')
|
||
|
|
||
|
// 在组件挂载和卸载时添加和移除事件监听
|
||
|
onMounted(() => {
|
||
|
window.addEventListener('scroll', debouncedScroll)
|
||
|
})
|
||
|
|
||
|
onUnmounted(() => {
|
||
|
window.removeEventListener('scroll', debouncedScroll)
|
||
|
})
|
||
|
</script>
|
||
|
|
||
|
<template>
|
||
|
<nav :class="{'bg-transparent': !scrolled && !alwaysBlueBackground,
|
||
|
'bg-blue-400': scrolled || alwaysBlueBackground,
|
||
|
'shadow': scrolled}"
|
||
|
class="fixed top-0 z-20 h-16 w-full text-white transition-all duration-300"
|
||
|
>
|
||
|
<div class="container mx-auto flex h-16 w-full items-center justify-between px-4 md:px-0 xl:max-w-screen-xl">
|
||
|
<!-- 下拉菜单按钮 -->
|
||
|
<div class="flex h-8 w-10 items-center justify-center rounded-md border-gray-600 md:hidden"
|
||
|
@click="menuExpanded"
|
||
|
>
|
||
|
<font-awesome-icon :icon="['fas', 'bars']" class="h-6"/>
|
||
|
</div>
|
||
|
<!-- Logo -->
|
||
|
<div class="absolute left-1/2 -translate-x-1/2 md:relative md:left-0 md:translate-x-0">
|
||
|
<!-- 文字模式 -->
|
||
|
<div v-if="showLogo" class="h-full text-4xl min-w-16 logo py-3.5">
|
||
|
<span>CantyOni_on's Index</span>
|
||
|
</div>
|
||
|
<!-- 图片模式 -->
|
||
|
<div v-else class="py-2">
|
||
|
<img src="~/assets/images/logo/w.png" alt="" class="h-12 w-12"/>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<!-- Entry -->
|
||
|
<div :class="{'h-screen opacity-100 visible': isExpended, 'h-0 opacity-0 invisible': !isExpended}"
|
||
|
class="absolute top-full right-0 left-0 bg-white transition-all md:visible md:relative md:top-0 md:flex
|
||
|
md:h-auto md:bg-transparent md:opacity-100"
|
||
|
>
|
||
|
<nav-bar-entry-item v-for="item in entry" :key="item.title"
|
||
|
:entry="item.entry" :icon="item.icon"
|
||
|
:title="item.title" :to="item.to"
|
||
|
@on-go="menuClose"
|
||
|
/>
|
||
|
</div>
|
||
|
|
||
|
<!-- 快速跳转小组件 -->
|
||
|
<div class="flex items-center justify-between gap-4 text-xl">
|
||
|
<a v-for="item in littleWidget"
|
||
|
:key="item.url" :href=item.url :title=item.title
|
||
|
class="transition-all hover:scale-125">
|
||
|
<font-awesome-icon :icon="item.icon"/>
|
||
|
</a>
|
||
|
</div>
|
||
|
</div>
|
||
|
</nav>
|
||
|
</template>
|
||
|
|
||
|
<style scoped>
|
||
|
.logo {
|
||
|
font-family: BaconyScript, serif;
|
||
|
}
|
||
|
</style>
|