使用Vue3编写倒计时Hook
分析
hook本质上是一个函数,返回需要的数据,且使用在setup
函数中.很容易构想出函数应该是这样
const time = useCountdown();
且该函数需要返回倒计时的剩余天数,时分秒。像这样 01天13小时20分20秒。
另外倒计时的结束时间应该是可变的作为参数传进去
编写
完整代码
import { onBeforeUnmount, reactive } from 'vue';
/**
*
* 倒计时hook
*
* @example
* const time = useCountdown({
* endDate: '2021-12-31 12:30:00',
* })
*
* @param {Object} arg
* @param {String|Number} arg.endDate - 结束时间。例如 '2021-12-31 12:30:00'或一个毫秒时间戳 1640930400000
* @returns {{s: string, d: string, h: string, m: string}} - 对象,其中 d:天数 h:时 m:分 s:秒
*/
function useCountdown(arg) {
const { endDate: ed } = arg;
let intervalId = null;
let timeoutId = null;
const value = reactive({
d: '00',
h: '00',
m: '00',
s: '00',
});
//获取当前时间
const now = new Date().getTime();
//设置截止时间
const end = new Date(ed).getTime();
//时间差
let leftTime = end - now;
const callback = (minus = 1000) => {
leftTime -= minus;
if (leftTime >= 0) {
value.d = padZero(Math.floor(leftTime / 1000 / 60 / 60 / 24));
value.h = padZero(Math.floor(leftTime / 1000 / 60 / 60 % 24));
value.m = padZero(Math.floor(leftTime / 1000 / 60 % 60));
value.s = padZero(Math.floor(leftTime / 1000 % 60));
} else {
clearInterval(intervalId);
}
};
// 计算是否是整秒
const remain = leftTime % 1000;
if (remain === 0) {
intervalId = setInterval(callback, 1000);
} else {
timeoutId = setTimeout(() => {
callback(remain);
intervalId = setInterval(callback, 1000);
}, remain);
}
onBeforeUnmount(() => {
clearInterval(intervalId);
clearTimeout(timeoutId);
});
return value;
}
export default useCountdown;
const padZero = (str) => {
return str.toString().length === 1 ? `0${str}` : str;
};
使用
在setup
中使用
import useCountdown from '@/hooks/useCountdown'
export default{
setup(){
const time = useCountdown({
endDate:'2021-12-31 12:00:00'
})
return {
time
}
}
}