From b71ab1a34200da3ce2239645d1f9359a1fa48306 Mon Sep 17 00:00:00 2001 From: chenchun Date: Tue, 28 Apr 2026 14:32:57 +0800 Subject: [PATCH] =?UTF-8?q?feat(tools):=20=E6=B7=BB=E5=8A=A0=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E7=AE=B1=E9=A1=B5=E9=9D=A2=E5=8F=8A=E5=9B=BD=E9=99=85?= =?UTF-8?q?=E5=8C=96=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加新的工具箱页面,包含三个实用工具卡片。更新国际化文件支持多语言显示。优化页面滚动锁定功能,使其可配置自定义类名。调整导航栏菜单项显示逻辑。 工具箱页面包含入场动画效果,并添加SEO元信息。滚动锁定功能现在支持自定义类名,便于不同场景使用。导航栏现在动态显示中间菜单项,排除最后一项。 --- app/assets/css/tailwind.css | 5 + app/components/common/AppLoader.vue | 5 +- app/components/layouts/ArcticNewOneHeader.vue | 5 +- app/composables/usePageScrollLock.ts | 16 +- app/pages/tools.vue | 156 ++++++++++++++++++ i18n/locales/en.json | 11 ++ i18n/locales/zh.json | 11 ++ 7 files changed, 198 insertions(+), 11 deletions(-) create mode 100644 app/pages/tools.vue diff --git a/app/assets/css/tailwind.css b/app/assets/css/tailwind.css index 97444cc..a89fbcf 100644 --- a/app/assets/css/tailwind.css +++ b/app/assets/css/tailwind.css @@ -23,6 +23,11 @@ height: 0; } + html.is-scroll-locked, + html.is-scroll-locked body { + overflow: hidden !important; + } + /* 首页入场动画期间首帧就隐藏滚动条,避免黑色遮罩边缘露出白色滚动槽。 */ html.is-home-intro-active, html.is-home-intro-active body { diff --git a/app/components/common/AppLoader.vue b/app/components/common/AppLoader.vue index 6e4eb69..f4ae5fc 100644 --- a/app/components/common/AppLoader.vue +++ b/app/components/common/AppLoader.vue @@ -9,7 +9,7 @@ const loaderBarRef = ref(null) const appStore = useAppStore() // 加载期间锁定页面滚动(注意:Pinia 的 state 是自动解包的,必须用 computed 包装才能保持响应式) -usePageScrollLock(computed(() => appStore.isAppLoading)) +usePageScrollLock(computed(() => appStore.isAppLoading), { className: 'is-scroll-locked' }) let loaderTween: gsap.core.Tween | null = null let removeLoadListener: (() => void) | null = null @@ -49,7 +49,8 @@ onMounted(() => { gsap.timeline({ onComplete: () => { gsap.set(loaderRef.value, { display: 'none' }) - appStore.setAppLoading(false) // 触发全局状态,通知其他组件入场 + appStore.setAppLoading(false) + window.dispatchEvent(new CustomEvent('app-loading-done')) } }) .to(loaderBarRef.value, { scaleX: 1, duration: 0.25, ease: 'power2.out' }) diff --git a/app/components/layouts/ArcticNewOneHeader.vue b/app/components/layouts/ArcticNewOneHeader.vue index 5e31b4b..46fcbda 100644 --- a/app/components/layouts/ArcticNewOneHeader.vue +++ b/app/components/layouts/ArcticNewOneHeader.vue @@ -19,6 +19,7 @@ const navItems = computed>(() => [ { name: t('nav.studio'), path: '/studio' }, { name: t('nav.work'), path: '/work' }, { name: t('nav.news'), path: '/news' }, + { name: t('nav.tools'), path: '/tools' }, { name: t('nav.contact'), path: '/contact' } ]) @@ -250,9 +251,9 @@ onBeforeUnmount(() => { - +