feat(tools): 添加工具箱页面及国际化支持

添加新的工具箱页面,包含三个实用工具卡片。更新国际化文件支持多语言显示。优化页面滚动锁定功能,使其可配置自定义类名。调整导航栏菜单项显示逻辑。

工具箱页面包含入场动画效果,并添加SEO元信息。滚动锁定功能现在支持自定义类名,便于不同场景使用。导航栏现在动态显示中间菜单项,排除最后一项。
This commit is contained in:
2026-04-28 14:32:57 +08:00
parent 6aa61cc78f
commit b71ab1a342
7 changed files with 198 additions and 11 deletions
+9 -7
View File
@@ -1,22 +1,24 @@
import { onBeforeUnmount, watch, type Ref, isRef, unref, computed } from 'vue'
import { onBeforeUnmount, watch, type Ref, isRef, unref } from 'vue'
import { useNuxtApp, useHead } from '#imports'
// 全局模块级变量,用于记录锁定请求的次数,解决多组件并发锁定的竞态问题
let lenisLockCount = 0
export const usePageScrollLock = (isLocked: Ref<boolean> | boolean) => {
export const usePageScrollLock = (
isLocked: Ref<boolean> | boolean,
options?: { className?: string }
) => {
const nuxtApp = useNuxtApp()
// 由于 $lenis 是从 client 插件中注入的,SSR 期间可能为 undefined
// 而且在 setup 期间解构可能拿不到最新的值,我们改为在函数内部动态获取
// SSR 和 CSR 都支持:自动将 class 注入到 HTML 标签上
useHead({
htmlAttrs: {
class: computed(() => unref(isLocked) ? 'is-home-intro-active' : ''),
lang: 'zh-CN',
},
})
const lockClassName = options?.className ?? 'is-home-intro-active'
let currentlyLocked = false
const updateLock = (locked: boolean) => {
@@ -30,7 +32,7 @@ export const usePageScrollLock = (isLocked: Ref<boolean> | boolean) => {
lenisLockCount++
// 只有第一个锁请求时,才真正停止 Lenis 并滚动到顶部
if (lenisLockCount === 1) {
document.documentElement.classList.add('is-home-intro-active')
document.documentElement.classList.add(lockClassName)
// 注意:需要在这里动态获取 $lenis,因为此时 client 插件才可能挂载完成
const lenisInstance = nuxtApp.$lenis
if (lenisInstance) {
@@ -42,7 +44,7 @@ export const usePageScrollLock = (isLocked: Ref<boolean> | boolean) => {
lenisLockCount = Math.max(0, lenisLockCount - 1)
// 只有当所有锁请求都释放时,才重新启动 Lenis
if (lenisLockCount === 0) {
document.documentElement.classList.remove('is-home-intro-active')
document.documentElement.classList.remove(lockClassName)
// 同理,动态获取
const lenisInstance = nuxtApp.$lenis
if (lenisInstance) {