| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- <template>
- <slot name="renderText" :time="countdown.current.value">
- <Text v-bind="$attrs" :text="formatText()" />
- </slot>
- </template>
- <script setup lang="ts">
- import Text, { type TextProps } from '@/components/basic/Text.vue';
- import { useCountDown } from './CountdownHook';
- import { onBeforeUnmount, onMounted, watch } from 'vue';
- import { FormatUtils } from '@imengyu/imengyu-utils';
- export interface CountDownProps extends TextProps {
- /**
- * 倒计时时长,单位毫秒
- * @default 0
- */
- time?: number;
- /**
- * 时间格式
- * @default 'HH:mm:ss'
- */
- format?: string;
- /**
- * 是否自动开始倒计时
- * @default true
- */
- autoStart?: boolean;
- /**
- * 是否开启毫秒级渲染
- * @default false
- */
- millisecond?: boolean;
- }
- export interface CountDownInstance {
- start: () => void;
- stop: () => void;
- reset: (time?: number) => void;
- }
- const emit = defineEmits<{
- /**
- * 倒计时结束事件
- */
- (e: 'finish'): void;
- }>();
- const props = withDefaults(defineProps<CountDownProps>(), {
- time: 0,
- format: 'HH:mm:ss',
- autoStart: true,
- millisecond: false,
- });
- const countdown = useCountDown({
- time: props.time || 0,
- millisecond: props.millisecond || false,
- onFinish: () => emit('finish'),
- });
- watch(() => props.time, () => {
- countdown.reset(props.time);
- });
- onMounted(() => {
- if (props.autoStart !== false)
- countdown.start();
- });
- onBeforeUnmount(() => {
- countdown.stop();
- });
- defineExpose<CountDownInstance>({
- start() { countdown.start(); },
- stop() { countdown.stop(); },
- reset(time) { countdown.reset(time); },
- });
- function formatText() {
- let str = props.format ? props.format : "HH:mm:ss";
- str = str.replace(/DD/, FormatUtils.formatNumberWithZero(countdown.current.value.days, 2));
- str = str.replace(/HH/, FormatUtils.formatNumberWithZero(countdown.current.value.hours, 2));
- str = str.replace(/mm/, FormatUtils.formatNumberWithZero(countdown.current.value.minutes, 2));
- str = str.replace(/ss/, FormatUtils.formatNumberWithZero(countdown.current.value.seconds, 2));
- str = str.replace(/SSS/, FormatUtils.formatNumberWithZero(countdown.current.value.milliseconds, 3));
- str = str.replace(/SS/, FormatUtils.formatNumberWithZero(Math.floor(countdown.current.value.milliseconds / 10), 2));
- str = str.replace(/S/, Math.floor(countdown.current.value.milliseconds / 100).toString());
- return str;
- }
- </script>
|