ant-design-vue/components/statistic/Countdown.tsx

92 lines
2.2 KiB
Vue
Raw Normal View History

2021-06-10 15:04:57 +00:00
import { defineComponent, onBeforeUnmount, onMounted, onUpdated, ref } from 'vue';
2020-10-17 03:51:17 +00:00
import initDefaultProps from '../_util/props-util/initDefaultProps';
2021-06-23 13:47:53 +00:00
import Statistic, { statisticProps } from './Statistic';
2021-06-26 01:35:40 +00:00
import type { countdownValueType, FormatConfig } from './utils';
import { formatCountdown as formatCD } from './utils';
const REFRESH_INTERVAL = 1000 / 30;
2020-10-17 03:51:17 +00:00
function getTime(value?: countdownValueType) {
2021-08-05 06:36:50 +00:00
return new Date(value as any).getTime();
}
2020-10-17 03:51:17 +00:00
export default defineComponent({
name: 'AStatisticCountdown',
2021-06-23 13:47:53 +00:00
props: initDefaultProps(statisticProps, {
2020-10-17 03:51:17 +00:00
format: 'HH:mm:ss',
}),
2021-06-10 15:04:57 +00:00
emits: ['finish', 'change'],
setup(props, { emit }) {
const countdownId = ref<number>();
const statistic = ref();
const syncTimer = () => {
const { value } = props;
2020-10-17 03:51:17 +00:00
const timestamp = getTime(value);
if (timestamp >= Date.now()) {
2021-06-10 15:04:57 +00:00
startTimer();
} else {
2021-06-10 15:04:57 +00:00
stopTimer();
}
2021-06-10 15:04:57 +00:00
};
2021-06-10 15:04:57 +00:00
const startTimer = () => {
if (countdownId.value) return;
const timestamp = getTime(props.value);
countdownId.value = window.setInterval(() => {
statistic.value.$forceUpdate();
if (timestamp > Date.now()) {
emit('change', timestamp - Date.now());
}
syncTimer();
}, REFRESH_INTERVAL);
2021-06-10 15:04:57 +00:00
};
2021-06-10 15:04:57 +00:00
const stopTimer = () => {
const { value } = props;
2021-06-11 14:06:25 +00:00
if (countdownId.value) {
2021-06-10 15:04:57 +00:00
clearInterval(countdownId.value);
countdownId.value = undefined;
2020-10-17 03:51:17 +00:00
const timestamp = getTime(value);
if (timestamp < Date.now()) {
2021-06-10 15:04:57 +00:00
emit('finish');
}
}
2021-06-10 15:04:57 +00:00
};
2021-06-10 15:04:57 +00:00
const formatCountdown = ({
value,
config,
}: {
value: countdownValueType;
config: FormatConfig;
}) => {
const { format } = props;
return formatCD(value, { ...config, format });
};
2021-06-10 15:04:57 +00:00
const valueRenderHtml = (node: any) => node;
onMounted(() => {
syncTimer();
});
onUpdated(() => {
syncTimer();
});
onBeforeUnmount(() => {
stopTimer();
});
return () => {
return (
<Statistic
ref={statistic}
{...{
...props,
valueRender: valueRenderHtml,
formatter: formatCountdown,
}}
/>
);
};
},
});