ts+vue3+elementplus发送验证码实现(含倒计时重新发送)

137 阅读1分钟

效果展示: 在这里插入图片描述

<template>
  <el-form :model="formValue" :rules="rules" ref="form">
    <el-form-item prop="phone">
      <el-input v-model.number="formValue.phone" class="form-input" placeholder="请输入手机号" />
    </el-form-item>
    <el-form-item prop="validationCode">
      <el-input v-model.number="formValue.validationCode" class="form-input" placeholder="请输入验证码">
        <template #suffix>
          <span id="suffix-span">
            <span>|</span>
            <span id="suffix-span-2" @click="sendValidationCode(formValue.phone)" ref="spanRef">
              {{ isSendValidationCode }}
            </span>
          </span>
        </template>
      </el-input>
    </el-form-item>
    ...
  </el-form>
</template>
<script setup lang="ts">
import { sendCheckCode } from '@/api'

// 表单组件引用
const form = ref<FormInstance>()
// 接收form
const formValue = ref({
  phone: '',
  validationCode: ''
})
// 验证码区域文字说明
const spanRef = ref()
const isSendValidationCode = ref<string>('发送验证码')
// 发送验证码
async function sendValidationCode(phone: string) {
  // 用户是否已同意协议,未同意显示提示并不再执行
  if (!checkAgree.value) {
    showCheck.value = true
    return
  }
  // 若显示的发送验证码区域文字 不是 '发送验证码',就直接返回不再执行
  if (!isSendValidationCode.value.endsWith('发送验证码')) return
  await form.value!.validateField('phone') // 表单验证
  // 重新发送逻辑
  isSendValidationCode.value = '60秒后重新发送'
  spanRef.value.style = 'color: gray;' // 颜色变灰
  const countDown = ref<number>(60) // 倒计时
  const temp = setInterval(() => {
    countDown.value--
    isSendValidationCode.value = countDown.value + '秒后重新发送'
    if (!countDown.value) {
      clearInterval(temp)
      spanRef.value.style = 'color: #1764FF;' // 颜色变蓝
      isSendValidationCode.value = '重新发送验证码'
      countDown.value = 60
    }
  }, 1000)
  // 发送
  try {
    const res = await sendCheckCode({ username: phone }) // 返回boolean
    if (res) ElMessage.success('验证码发送成功')
  } catch {
    ElMessage.error('验证码发送失败')
  }
}
</script>