<template>
<a-button
type="primary"
class="mr--3"
@click="onStart"
:disabled="props?.disabled || state.remain > 0"
v-bind="$attrs"
>
{{ state.remain > 0 ? `重新发送(${state.remain}s)` : '获取验证码' }}
</a-button>
</template>
<script setup lang="ts">
import { nextTick, onMounted, reactive } from 'vue'
const props = defineProps<{
// 倒计时多少秒默认:30
target?: number
name?: string
disabled?: boolean
}>()
const emits = defineEmits<{
start: any[]
}>()
const state = reactive({
remain: 0
})
const sessName = `cd-${props?.name ?? 'sms'}`
let timer: number
const onStart = async () => {
const sec = props?.target ?? 30
setSec(sec)
await nextTick()
cd()
emits('start')
}
const setSec = (sec) => {
state.remain = sec
sessionStorage.setItem(sessName, String(sec))
}
const cd = () => {
const sec = state.remain
if (sec <= 0) {
clearTimeout(timer)
setSec(0)
return
}
timer = setTimeout(() => {
state.remain = sec - 1
setSec(sec - 1)
cd()
}, 1000)
}
onMounted(() => {
const cached = sessionStorage.getItem(sessName)
if (cached) {
state.remain = Number(cached)
cd()
}
})
</script>
使用
<template #suffix>
<ButtonCountdown
@start="onSendCode"
:loading="getCodeLoading"
:disabled="form.mobile === ''"
/>
</template>
Comments | NOTHING