Vue3 implements verification code countdown

foreword

Scenarios for the countdown: Countdown to obtain the mobile phone verification code, countdown to obtain the email verification code, etc. Let’s start without further ado.

achieve effect

insert image description here
insert image description here

Implementation code

html (important part)

<template>
  <el-button v-if="!sms.disabled" color="#f38301" type="default" @click="send"><span style="color:#eed2b0;">发送验证码</span></el-button>
  <el-button v-else type="default" color="#f38301" disabled><span style="color:#eed2b0;">{
   
   { sms.count }} 秒后重新发送</span></el-button>
</template>

js (important part)

<script lang="ts" setup>
  // 验证码计时器
  const sms = reactive({
      
      
	disabled: false,
	total: 60,
	count: 0
  })
  // 计时器处理器
  const timerHandler = () => {
      
      
	sms.count = sms.total
	sms.disabled = true

	let timer = setInterval(() => {
      
      
		if (sms.count > 1 && sms.count <= sms.total) {
      
      
			sms.count--
		} else {
      
      
			sms.disabled = false
			clearInterval(timer)
		}
	}, 1000)
    }
    // 推送
    const send = () => {
      
        
      if (formLabelAlign.username === '') {
      
      
        ElMessage.error("电子邮件为空")
      } else {
      
      
        // 计时器处理器
        timerHandler()
        // 加载ui
        const loadingInstance1 =  ElLoading.service({
      
      fullscreen: true})
        // api 请求
        return emailRegisterApi(formLabelAlign.username).then(res => {
      
      
        // 关闭加载
        loadingInstance1.close()
	  }).catch(() => {
      
      
        // 关闭加载
        loadingInstance1.close()
     })
  }
</script>

full code

<template>
  <div class="email-main">
    <div class="email-content">
      <div class="email-title">
        <h3>注册报名</h3>
      </div>
      <div class="email-step">
        <el-steps :active="active" finish-status="success" align-center="true">
        <el-step title="邮箱注册" />
        <el-step title="填写报名信息" />
        <el-step title="完成" />
        </el-steps>
      </div>
      <div class="email-table">
        <el-form
        ref="formRef"
        label-position="right"
        :model="formLabelAlign"
        style="width: 460px"
        label-width="100px"
        size="default"
        >
        <el-form-item prop="username" label="邮箱账号">
          <el-input v-model="formLabelAlign.username" />
        </el-form-item>
        <el-form-item prop="region"  label="设置密码">
          <el-input v-model="formLabelAlign.password" />
        </el-form-item>
        <el-form-item prop="code"  label="验证码">
          <el-input v-model="formLabelAlign.code" />
        </el-form-item>
        <el-form-item style="margin-left:50px;">
          <el-button color="#f38301" @click="submitForm">
            <span style="color:#eed2b0;">下一步</span>
          </el-button>
          <el-button color="#f38301" @click="resetForm(formRef)"> <span style="color: #eed2b0;">重置</span></el-button>
		      <el-button v-if="!sms.disabled" color="#f38301" type="default" @click="send"><span style="color:#eed2b0;">发送验证码</span></el-button>
			    <el-button v-else type="default" color="#f38301" disabled><span style="color:#eed2b0;">{
   
   { sms.count }} 秒后重新发送</span></el-button>
        </el-form-item>
        </el-form>
      </div>
    </div>
  </div>
</template>
<script lang="ts" setup>
import {
      
       ref,reactive } from 'vue'
import {
      
       FormInstance, ElLoading, ElMessage  } from 'element-plus'
import {
      
       emailRegisterApi } from '@/api/facade/facade'
import {
      
       useRouter } from 'vue-router'
// 路由
const router = useRouter()
// 步骤标识
const active = ref(0)
// 重置
const formRef = ref<FormInstance>()
// 注册参数
const formLabelAlign = reactive({
      
      
  username: '',
  password: '',
  code: '',
})
// 验证码计时器
const sms = reactive({
      
      
	disabled: false,
	total: 60,
	count: 0
})

// 计时器处理器
const timerHandler = () => {
      
      
	sms.count = sms.total
	sms.disabled = true

	let timer = setInterval(() => {
      
      
		if (sms.count > 1 && sms.count <= sms.total) {
      
      
			sms.count--
		} else {
      
      
			sms.disabled = false
			clearInterval(timer)
		}
	}, 1000)
}

const resetForm = (formEl: FormInstance | undefined) => {
      
      
  if (!formEl) return
  formEl.resetFields()
}
// 下一步
const submitForm = () => {
      
      
  const loadingInstance1 =  ElLoading.service({
      
      fullscreen: true})
  if (formLabelAlign.username != '' && formLabelAlign.password != '' && formLabelAlign.code != '') {
      
      
    // 跳转到报名页面
    router.push({
      
       path: '/sign_up_info', query: {
      
      username: formLabelAlign.username,
    password: formLabelAlign.password, code: formLabelAlign.code} })
  } else {
      
      
     ElMessage.warning("请完善全部信息")
  }
  loadingInstance1.close()
}
const send = () => {
      
      
  console.log('codeDisabled:',formLabelAlign.username)
  
  if (formLabelAlign.username === '') {
      
      
    ElMessage.error("电子邮件为空")
  } else {
      
      
    timerHandler()
    const loadingInstance1 =  ElLoading.service({
      
      fullscreen: true})
    return emailRegisterApi(formLabelAlign.username).then(res => {
      
      
    loadingInstance1.close()
	  }).catch(() => {
      
      
      ElMessage.error("Email数据异常")
      loadingInstance1.close()
  })
  }
}
</script>

<style scoped>
.email-main {
      
      
  height: 100%;
  width: 100%;
  position: relative;
}
.email-content {
      
      
  width: 1200px;
  height: 800px;
  border: 1px;
  position: relative;
  left: 400px;
  background: #f1f3f5;
}
.email-title {
      
      
  top: 30px;
  position: relative;
  left: 570px;
  margin-top: 100px;
}
.email-step {
      
      
  left: 100px;
  top: 0px;
  position: absolute;
  margin-top: 100px;
  width: 1000px;
}
.email-table {
      
      
  left: 350px;
  top: 200px;
  position: absolute;
}
:deep(.el-step__icon.is-text){
      
       
  border-radius: 50%;
  border: 2px solid #f38301;
  background: #f38301;
  color: #f1f3f5;
 }
</style>

Guess you like

Origin blog.csdn.net/qq_44697754/article/details/128574525