Vue3 验证码倒计时组件


<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>

声明:八零秘林|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - Vue3 验证码倒计时组件


记忆碎片 · 精神拾荒