| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- <template>
- <div class="verification-code-input">
- <el-form-item prop="code" :rules="[
- { required: true, message: '请输入验证码'}
- ]">
- <!-- 输入框 -->
- <el-input @keydown.enter="debouncedSendAuthCode" class="bf-login-form-code" oninput="this.value = this.value.replace(/[^0-9]/g, '')" minlength="6"
- maxlength="6" v-model.number="code" clearable
- placeholder="请输入验证码"/>
- <!-- 获取验证码按钮 -->
- <el-button @click="debouncedSendAuthCode" class="bf-login-form-code-btn" type="primary"
- :disabled="countdownActive">
- {{ countdownActive ? `${remainingTime} 秒后重新获取` : '获取验证码' }}
- </el-button>
- </el-form-item>
- </div>
- </template>
- <script setup lang="ts">
- import {ref, onBeforeUnmount} from 'vue';
- import {debounce} from "@/utils/common.ts";
- // 使用 defineEmits 声明组件可以发射的事件
- const emits = defineEmits(['sendAuthCode']);
- // 组件内部的状态
- const code = defineModel('code');
- const countdown = ref<NodeJS.Timeout | null>(null);
- const countdownDuration = 60;
- const remainingTime = ref(countdownDuration);
- const countdownActive = ref(false);
- // 防抖处理获取验证码的函数
- const debouncedSendAuthCode = debounce(sendAuthCode, 500);
- // 发送验证码的函数
- function sendAuthCode() {
- // 如果正在倒计时,直接返回,防止连续点击
- if (countdownActive.value) return;
- // 通过发射事件通知父组件,同时传递启动倒计时的回调函数
- emits('sendAuthCode', startCountdown);
- }
- // 启动倒计时的函数
- function startCountdown() {
- countdownActive.value = true;
- // 设置间隔为1秒的定时器,更新剩余时间
- countdown.value = setInterval(() => {
- remainingTime.value--;
- // 当剩余时间为0时清除定时器,重置状态
- if (remainingTime.value <= 0) {
- clearInterval(countdown.value!);
- countdownActive.value = false;
- remainingTime.value = countdownDuration;
- }
- }, 1000);
- }
- // 在组件销毁前清除倒计时器
- onBeforeUnmount(() => {
- clearInterval(countdown.value!);
- });
- </script>
- <style scoped lang="scss">
- :deep(.el-form-item__content) {
- flex-wrap: unset;
- }
- </style>
|