Files
arcticnewone/app/pages/index.vue
T
virtheart 76e7b4b817 refactor(components): 优化动画组件代码结构并移除冗余样式
style(pages): 使用实用类替换内联样式
refactor(composables): 简化页面标题模板逻辑
docs(components): 添加详细注释说明动画逻辑
2026-04-27 02:28:49 +08:00

75 lines
2.2 KiB
Vue

<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import { useUserStore } from '~/stores/user'
import { useAppStore } from '~/stores/app'
import { usePageScrollLock } from '~/composables/usePageScrollLock'
import HomeIntro from '~/components/home/HomeIntro.vue'
import HomeHero from '~/components/home/HomeHero.vue'
const { t } = useI18n()
const userStore = useUserStore()
const appStore = useAppStore()
const isIntroActive = ref(true)
const demoUserName = computed(() => userStore.displayName)
const demoUserRole = computed(() => userStore.role)
if (!userStore.isLoggedIn) {
userStore.loadDemoUser()
}
// 让首屏入场的锁滚动在 SSR/首帧就生效,避免等 onMounted 才隐藏滚动条。
useHead({
htmlAttrs: {
class: computed(() => (isIntroActive.value ? 'is-home-intro-active' : undefined)),
},
})
// 使用组合式函数管理 Lenis 滚动锁定
usePageScrollLock(isIntroActive)
// 首页的 SEO 和 Meta 优化,支持国际化响应式
useSeoMeta({
title: () => t('home.title'),
description: () => t('home.welcome'),
ogTitle: () => `${t('home.title')} - ${t('app.name')}`,
ogDescription: () => t('home.welcome'),
twitterTitle: () => `${t('home.title')} - ${t('app.name')}`,
twitterDescription: () => t('home.welcome'),
})
const homeIntroRef = ref<InstanceType<typeof HomeIntro> | null>(null)
const homeHeroRef = ref<InstanceType<typeof HomeHero> | null>(null)
// 监听全局加载状态,加载完成后依次播放开场和首屏动画
watch(() => appStore.isAppLoading, async (isLoading) => {
if (!isLoading) {
await homeIntroRef.value?.play()
await homeHeroRef.value?.play()
// 动画播放完毕后解除页面滚动锁定
isIntroActive.value = false
}
}, { immediate: true })
</script>
<template>
<main
id="top"
:data-demo-user="demoUserName"
:data-demo-user-role="demoUserRole"
>
<HomeIntro ref="homeIntroRef" />
<HomeHero ref="homeHeroRef" />
<section class="grid min-h-[100svh] place-items-center">
<h2>Next Section</h2>
</section>
<section id="work" class="grid min-h-[100svh] place-items-center" data-cursor-label="Read more">
<p>{{ t('home.welcome') }}</p>
</section>
</main>
</template>