<template> <div class="ps-send" :class="{ ['ps-send--'+size]: size? true: false, ['ps-send--border']: border }" @click="onClick" :disabled="isDisabled" :loading="isLoading" type="button" size="small"> {{ text }} </div> <Abutton>asd</Abutton> </template> <script lang="ts" setup> import { onBeforeUnmount, ref } from "vue" import Abutton from "@princess-ui/components/button" const props = withDefaults( defineProps<{ duration?: number initText?: string runText?: string loadingText?: string resetText?: string border?: boolean size?: "small" | "big" }>(), { runText: "{%s}s 后重新发送", initText: "获取验证码", loadingText: "正在发送", resetText: "重新获取", border: false, duration: 60, }, ) const emits = defineEmits<{ (event: "update:modelValue", show: boolean): void (event: "send", start: () => void, done: (isDone?: boolean) => void): void }>() const text = ref(props.initText) const isDisabled = ref(false) const isLoading = ref(false) let timeID: any onBeforeUnmount(() => { stop() }) function stop() { clearInterval(timeID) text.value = props.resetText isLoading.value = false isDisabled.value = false emits("update:modelValue", false) } //获取格式化 function getText(second: string | number): string { return props.runText.replace(/\{([^{]*?)%s(.*?)\}/g, String(second)) } function run() { isLoading.value = false let number = props.duration text.value = getText(number) clearInterval(timeID) timeID = setInterval(() => { number-- text.value = getText(number) if (number <= 0) { stop() } }, 1000) } function onClick() { if (isDisabled.value) return if (isLoading.value) return emits( "send", () => { isDisabled.value = true isLoading.value = true text.value = props.loadingText }, (isDone: boolean = true) => { if (isDone) { run() } else { stop() } }, ) } </script>