自学内容网 自学内容网

Typescript 实现倒计时功能 useCountdown

效果图

代码块

useCountdown.ts

import {onUnmounted, reactive, ref, watch} from "vue";

type union = 'days' | 'hours' | 'minutes' | 'seconds' | 'milliseconds'

export type Remains = Record<union, number>;

/**
 * 创建一个倒计时
 *
 * 用法
 */
export const useCountDown = () => {
    const remainMilliseconds = ref();
    const started = ref(false);
    const finished = ref<boolean>();
    const remains = reactive<Remains>({
        days: 0,
        hours: 0,
        minutes: 0,
        seconds: 0,
        milliseconds: 0,
    });

    const start = (deadline: number) => {
        if (started.value) {
            return
        }
        started.value = true
        loop(deadline)
    }

    const loop = (deadline: number) => {
        if (typeof requestAnimationFrame == 'function') {
            if (started.value) {
                requestAnimationFrame(() => {
                    const nowTime = new Date().getTime();
                    remainMilliseconds.value = deadline - nowTime;
                    finished.value = remainMilliseconds.value <= 0
                    if (finished.value) {
                        stop()
                    }
                    loop(deadline)
                })
            }
        } else {
            // 降级使用定时器
            const interval = setInterval(() => {
                const nowTime = new Date().getTime();
                remainMilliseconds.value = deadline - nowTime;
                finished.value = remainMilliseconds.value <= 0
                if (finished.value) {
                    stop()
                    clearInterval(interval)
                }
            }, 16);
        }
    }

    const stop = () => {
        started.value = false
    }

    watch(remainMilliseconds, (value) => {
        remains.days = Math.max((value / 1000 / 60 / 60 / 24 | 0), 0)
        remains.hours = Math.max((value / 1000 / 60 / 60 % 24 | 0), 0)
        remains.minutes = Math.max((value / 1000 / 60 % 60 | 0), 0)
        remains.seconds = Math.max((value / 1000 % 60 | 0), 0)
        remains.milliseconds = Math.max((value % 1000 | 0), 0)
    })

    onUnmounted(stop)

    return {finished, remains, start, stop}
}

vue

<template>
{{remains.days}}天
{{remains.hours}}时
{{remains.minutes}}分钟
{{remains.seconds}}秒
</template>

<script setup lang="ts">
import { watch } from 'vue';
import { useCountDown } from './useCountDown';
const { remains,finished, start } = useCountDown()
start(new Date().getTime() + 10 * 10000000)
watch(finished,(n:boolean)=>{
if(n){
alert('done')
}
})
</script>

<style lang="scss">
</style>


原文地址:https://blog.csdn.net/LJM51200/article/details/140504933

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!