diff --git a/src/composables/useScrollLock.ts b/src/composables/useScrollLock.ts deleted file mode 100644 index 1867e61c..00000000 --- a/src/composables/useScrollLock.ts +++ /dev/null @@ -1,159 +0,0 @@ -import { ref, watch, onBeforeUnmount, readonly } from 'vue' - -// 滚动锁定配置选项 -export interface ScrollLockOptions { - // 是否在组件卸载时自动恢复滚动(默认true) - autoRestore?: boolean - // 是否保存和恢复滚动位置(默认true) - preserveScrollPosition?: boolean - // 自定义锁定时的样式 - lockStyles?: { - overflow?: string - position?: string - width?: string - } -} - -// 默认配置 -const DEFAULT_OPTIONS: Required = { - autoRestore: true, - preserveScrollPosition: true, - lockStyles: { - overflow: 'hidden', - position: 'fixed', - width: '100%', - }, -} - -export function useScrollLock(options: ScrollLockOptions = {}) { - const config = { ...DEFAULT_OPTIONS, ...options } - - // 状态管理 - const isLocked = ref(false) - const savedScrollPosition = ref(0) - const originalBodyStyles = ref<{ [key: string]: string }>({}) - const originalDocumentStyles = ref<{ [key: string]: string }>({}) - - // 保存当前滚动位置 - const saveScrollPosition = () => { - if (config.preserveScrollPosition) { - savedScrollPosition.value = - window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0 - } - } - - // 保存原始样式 - const saveOriginalStyles = () => { - // 保存 body 样式 - originalBodyStyles.value = { - overflow: document.body.style.overflow, - position: document.body.style.position, - top: document.body.style.top, - width: document.body.style.width, - } - - // 保存 documentElement 样式 - originalDocumentStyles.value = { - overflow: document.documentElement.style.overflow, - } - } - - // 锁定滚动 - const lockScroll = () => { - if (isLocked.value) return - - // 保存当前状态 - saveScrollPosition() - saveOriginalStyles() - - // 应用锁定样式 - document.body.style.overflow = config.lockStyles.overflow || 'hidden' - document.body.style.position = config.lockStyles.position || 'fixed' - document.body.style.width = config.lockStyles.width || '100%' - document.documentElement.style.overflow = config.lockStyles.overflow || 'hidden' - - // 如果需要保持滚动位置,设置top偏移 - if (config.preserveScrollPosition) { - document.body.style.top = `-${savedScrollPosition.value}px` - } - - isLocked.value = true - } - - // 恢复滚动 - const restoreScroll = () => { - if (!isLocked.value) return - - // 恢复原始样式 - document.body.style.overflow = originalBodyStyles.value.overflow || '' - document.body.style.position = originalBodyStyles.value.position || '' - document.body.style.top = originalBodyStyles.value.top || '' - document.body.style.width = originalBodyStyles.value.width || '' - document.documentElement.style.overflow = originalDocumentStyles.value.overflow || '' - - // 恢复滚动位置 - if (config.preserveScrollPosition) { - window.scrollTo(0, savedScrollPosition.value) - } - - isLocked.value = false - } - - // 切换滚动锁定状态 - const toggleScrollLock = (lock?: boolean) => { - const shouldLock = lock !== undefined ? lock : !isLocked.value - - if (shouldLock) { - lockScroll() - } else { - restoreScroll() - } - } - - // 监听响应式值的变化 - const watchTarget = (target: any) => { - return watch( - target, - newValue => { - toggleScrollLock(!!newValue) - }, - { immediate: false }, - ) - } - - // 生命周期清理 - onBeforeUnmount(() => { - if (config.autoRestore && isLocked.value) { - restoreScroll() - } - }) - - return { - // 状态 - isLocked: readonly(isLocked), - savedScrollPosition: readonly(savedScrollPosition), - - // 方法 - lockScroll, - restoreScroll, - toggleScrollLock, - watchTarget, - - // 工具方法 - saveScrollPosition, - } -} - -// 便捷的自动监听版本 -export function useScrollLockWithWatch(target: any, options: ScrollLockOptions = {}) { - const scrollLock = useScrollLock(options) - - // 自动监听目标值的变化 - const stopWatcher = scrollLock.watchTarget(target) - - // 返回所有功能 + 停止监听的方法 - return { - ...scrollLock, - stopWatcher, - } -} diff --git a/src/layouts/components/DefaultLayout.vue b/src/layouts/components/DefaultLayout.vue index 5d29a996..d64d17f6 100644 --- a/src/layouts/components/DefaultLayout.vue +++ b/src/layouts/components/DefaultLayout.vue @@ -18,7 +18,7 @@ import { useRoute } from 'vue-router' import { filterMenusByPermission } from '@/utils/permission' import { onUnreadMessage } from '@/utils/badge' import { usePullDownGesture } from '@/composables/usePullDownGesture' -import { useScrollLockWithWatch } from '@/composables/useScrollLock' +import { useDialogScrollLockWithWatch } from '@/composables/useDialogScrollLock' import { usePWA } from '@/composables/usePWA' import OfflinePage from '@/layouts/components/OfflinePage.vue' import { useGlobalOfflineStatus } from '@/composables/useOfflineStatus' @@ -164,7 +164,7 @@ const handleServiceWorkerMessage = (event: MessageEvent) => { } // 使用滚动锁定 composable(自动监听showPluginQuickAccess的变化) -useScrollLockWithWatch(showPluginQuickAccess) +useDialogScrollLockWithWatch(showPluginQuickAccess) // 检查是否可以使用下拉手势 const canUsePullGesture = () => {