You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
58 lines
1.4 KiB
58 lines
1.4 KiB
<script lang="ts" setup> |
|
import { useI18n } from '@/hooks/web/useI18n' |
|
import { isFunction } from '@/utils/is' |
|
import { Button } from 'ant-design-vue' |
|
import { computed, ref, unref, watchEffect } from 'vue' |
|
import { useCountdown } from './useCountdown' |
|
|
|
defineOptions({ name: 'CountButton' }) |
|
|
|
const props = defineProps({ |
|
value: { type: [Object, Number, String, Array] }, |
|
count: { type: Number, default: 60 }, |
|
beforeStartFunc: { |
|
type: Function as PropType<() => Promise<any>>, |
|
default: null, |
|
}, |
|
}) |
|
|
|
const loading = ref(false) |
|
|
|
const { currentCount, isStart, start, reset } = useCountdown(props.count) |
|
const { t } = useI18n() |
|
|
|
const getButtonText = computed(() => { |
|
return !unref(isStart) ? t('component.countdown.normalText') : t('component.countdown.sendText', [unref(currentCount)]) |
|
}) |
|
|
|
watchEffect(() => { |
|
props.value === undefined && reset() |
|
}) |
|
|
|
/** |
|
* @description: Judge whether there is an external function before execution, and decide whether to start after execution |
|
*/ |
|
async function handleStart() { |
|
const { beforeStartFunc } = props |
|
if (beforeStartFunc && isFunction(beforeStartFunc)) { |
|
loading.value = true |
|
try { |
|
const canStart = await beforeStartFunc() |
|
if (canStart) |
|
start() |
|
} |
|
finally { |
|
loading.value = false |
|
} |
|
} |
|
else { |
|
start() |
|
} |
|
} |
|
</script> |
|
|
|
<template> |
|
<Button v-bind="$attrs" :disabled="isStart" :loading="loading" @click="handleStart"> |
|
{{ getButtonText }} |
|
</Button> |
|
</template>
|
|
|