// hook/useGlobalInactivity.js import { onMounted, onUnmounted } from 'vue' export function useGlobalInactivity(callback, timeout = 60000) { let timer = null let isPaused = false // ===== 高频事件节流 ===== let lastActivityTime = 0 const THROTTLE_DELAY = 300 // 300ms 内最多响应一次活动 const handleUserActivity = () => { const now = Date.now() if (now - lastActivityTime > THROTTLE_DELAY) { lastActivityTime = now resetTimer() } } // 低频事件(可直接绑定) const lowFreqEvents = ['mousedown', 'click', 'keydown', 'touchstart'] // 高频事件(需节流) const highFreqEvents = ['mousemove', 'scroll', 'wheel', 'pointermove'] const resetTimer = () => { if (isPaused) return if (timer) clearTimeout(timer) timer = setTimeout(() => { callback() pause() // 默认触发后停止 }, timeout) } const pause = () => { isPaused = true if (timer) { clearTimeout(timer) timer = null } lowFreqEvents.forEach(e => document.removeEventListener(e, resetTimer, true)) highFreqEvents.forEach(e => document.removeEventListener(e, handleUserActivity, true)) document.removeEventListener('visibilitychange', handleVisibilityChange) } const resume = () => { if (!isPaused) return isPaused = false resetTimer() lowFreqEvents.forEach(e => document.addEventListener(e, resetTimer, true)) highFreqEvents.forEach(e => document.addEventListener(e, handleUserActivity, true)) document.addEventListener('visibilitychange', handleVisibilityChange) } const handleVisibilityChange = () => { if (document.hidden) { pause() } else { resume() } } const start = () => { if (isPaused) return resetTimer() lowFreqEvents.forEach(e => document.addEventListener(e, resetTimer, true)) highFreqEvents.forEach(e => document.addEventListener(e, handleUserActivity, true)) document.addEventListener('visibilitychange', handleVisibilityChange) } onMounted(start) onUnmounted(pause) return { resume, pause } }