效果展示:
<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>