From 01484997932efe61bd187a67ee0eac6bfe6f54a0 Mon Sep 17 00:00:00 2001 From: hkaikai <617760820@qq.com> Date: Tue, 19 Nov 2024 12:28:20 +0800 Subject: [PATCH] =?UTF-8?q?fix(count-down):=20=E4=BF=AE=E5=A4=8D=E6=A0=87?= =?UTF-8?q?=E7=AD=BE=E9=A1=B5=E7=BD=AE=E4=BA=8E=E5=90=8E=E5=8F=B0=EF=BC=8C?= =?UTF-8?q?=E5=80=92=E8=AE=A1=E6=97=B6=E5=81=9C=E6=AD=A2=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20(#1631)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix #1213 --- src/count-down/count-down.tsx | 15 +++++++-- src/shared/useCountDown/index.ts | 52 +++++++++++++++++++------------- 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/src/count-down/count-down.tsx b/src/count-down/count-down.tsx index 09171d0d6..a55d8f01b 100644 --- a/src/count-down/count-down.tsx +++ b/src/count-down/count-down.tsx @@ -1,4 +1,4 @@ -import { computed, defineComponent } from 'vue'; +import { computed, defineComponent, onBeforeUnmount, onMounted, ref } from 'vue'; import config from '../config'; import CountDownProps from './props'; import { useCountDown } from '../shared/useCountDown'; @@ -18,8 +18,17 @@ export default defineComponent({ `${countDownClass.value}--${props.theme}`, `${countDownClass.value}--${props.size}`, ]); - - const { showTimes } = useCountDown(props); + const visibility = ref(true); + const visibilitychangeListener = () => { + visibility.value = !document.hidden; + }; + onMounted(() => { + document.addEventListener('visibilitychange', visibilitychangeListener, false); + }); + onBeforeUnmount(() => { + document.removeEventListener('visibilitychange', visibilitychangeListener, false); + }); + const { showTimes } = useCountDown(props, visibility); return () => { const renderContent = () => { const content = renderTNodeJSX('content'); diff --git a/src/shared/useCountDown/index.ts b/src/shared/useCountDown/index.ts index 7d28f71d9..03a19441b 100644 --- a/src/shared/useCountDown/index.ts +++ b/src/shared/useCountDown/index.ts @@ -1,10 +1,10 @@ -import { ref, reactive } from 'vue'; +import { ref, reactive, Ref, watch } from 'vue'; import { useRafFn } from '@vueuse/core'; import { TdUseCountDownProps, TdUseCountDown } from './type'; import { getRemainTimes, getShowTimes, getScreenFps } from './utils'; import { isBrowser } from '../util'; -export function useCountDown(props: TdUseCountDownProps): TdUseCountDown { +export function useCountDown(props: TdUseCountDownProps, visibility?: Ref): TdUseCountDown { const { time = 0, autoStart, @@ -18,27 +18,37 @@ export function useCountDown(props: TdUseCountDownProps): TdUseCountDown { const fps = ref(); const count = ref(Number(time)); const showTimes = reactive(getShowTimes(getRemainTimes(time), format, millisecond, splitWithUnit)); + let hiddenTime = 0; - // raf - const { pause, resume } = useRafFn( - async () => { - if (!isBrowser) return; - if (!fps.value) { - const res = await getScreenFps?.(); - fps.value = res || 60; - } - count.value = parseInt(`${Number(count.value) - 1000 / fps.value}`, 10); - if (count.value <= 0) { - pause?.(); - count.value = 0; + visibility && + watch(visibility, (val) => { + if (val) { + count.value -= Date.now() - hiddenTime; + rafFn(); + } else { + hiddenTime = Date.now(); } - const times = getRemainTimes(count.value); - onChange?.(times); - count.value === 0 && onFinish?.(); - getShowTimes(times, format, millisecond, splitWithUnit)?.forEach?.((i, idx) => (showTimes[idx].value = i?.value)); - }, - { immediate: autoStart }, - ); + }); + + const rafFn = async () => { + if (!isBrowser) return; + if (!fps.value) { + const res = await getScreenFps?.(); + fps.value = res || 60; + } + count.value = parseInt(`${Number(count.value) - 1000 / fps.value}`, 10); + if (count.value <= 0) { + pause?.(); + count.value = 0; + } + const times = getRemainTimes(count.value); + onChange?.(times); + count.value === 0 && onFinish?.(); + getShowTimes(times, format, millisecond, splitWithUnit)?.forEach?.((i, idx) => (showTimes[idx].value = i?.value)); + }; + + // raf + const { pause, resume } = useRafFn(rafFn, { immediate: autoStart }); /** * return