实现方法:监听用户操作事件(此方式个人认为有点挫,但能跑,如果有更好的方法欢迎留言讨论
新建useUserInteraction.ts
import {
ref, onMounted, onBeforeUnmount, Ref,
} from 'vue'
// 防抖
import { useDebounce } from 'xxxx'
export default function useUserInteraction(interval: number = 30000): {
countdownSeconds: Ref<number>
reset: () => void
} {
const countdownSeconds: Ref<number> = ref(interval / 1000)
let timeoutId: number | null = null
const startTimer = (): void => {
countdownSeconds.value = interval / 1000
let firstTick = true
const tick = (): void => {
if (!firstTick) {
countdownSeconds.value -= 1
}
if (countdownSeconds.value > 0) {
timeoutId = window.setTimeout(tick, 1000)
} else {
timeoutId = null
}
firstTick = false
}
tick()
}
const handleUserInteraction = useDebounce((): void => {
if (timeoutId !== null) {
window.clearTimeout(timeoutId)
}
startTimer()
}, { delay: 0 })
const reset = (): void => {
if (timeoutId !== null) {
window.clearTimeout(timeoutId)
}
}
onMounted(() => {
window.addEventListener('mousemove', handleUserInteraction)
window.addEventListener('mousedown', handleUserInteraction)
window.addEventListener('touchstart', handleUserInteraction)
window.addEventListener('touchmove', handleUserInteraction)
window.addEventListener('wheel', handleUserInteraction)
})
onBeforeUnmount(() => {
window.removeEventListener('mousemove', handleUserInteraction)
window.removeEventListener('mousedown', handleUserInteraction)
window.removeEventListener('touchstart', handleUserInteraction)
window.removeEventListener('touchmove', handleUserInteraction)
window.addEventListener('wheel', handleUserInteraction)
if (timeoutId) {
window.clearTimeout(timeoutId)
}
})
// 向外抛出用户无操作时间秒数和重置方法
return {
countdownSeconds,
reset,
}
}
使用方法
import useUserInteraction from '~/hooks/useUserInteraction'
const { countdownSeconds, reset: handleInteractionReset } = useUserInteraction(30000)
// 监听无操作倒计时
watch(() => countdownSeconds.value, val => {
if(val === 0) {
console.log('30秒内无操作')
}
})
// 可以通过reset重置倒计时,直到下一次用户操作事件才会被触发
// handleInteractionReset()