Files
cashier-web/src/components/resetPassword/CaptchaBtn.vue

123 lines
3.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<!-- 验证码按钮 - 纯功能高度定制版 -->
<el-button :type="buttonType" :size="buttonSize" :disabled="disabled || isCountingDown" :loading="isLoading"
class="captcha-btn" @click="handleGetCaptcha">
<!-- 倒计时状态展示 -->
<span v-if="isCountingDown">{{ countDown }} 秒后重新获取</span>
<!-- 正常状态展示 -->
<span v-else>{{ buttonText }}</span>
</el-button>
</template>
<script setup>
import { ref } from 'vue'
import { getSms } from "@/api/common";
// 接收父组件传递的自定义参数
const props = defineProps({
// 验证码类型
// editShopInfoOpePwd 店铺操作密码
// wxMiniPwd 微信小程序用户登录密码
// shopPwd 店铺登录密码
type: {
type: String,
default: 'editShopInfoOpePwd'
},
// 按钮类型primary/success/warning/danger/info/default
buttonType: {
type: String,
default: 'primary'
},
// 按钮尺寸large/default/small
buttonSize: {
type: String,
default: 'default'
},
// 正常状态按钮文字
buttonText: {
type: String,
default: '获取验证码'
},
// 倒计时总秒数
countDownNum: {
type: Number,
default: 60
},
// 手动控制按钮禁用状态
disabled: {
type: Boolean,
default: false
}
})
// 发射事件给父组件
const emit = defineEmits(['get-captcha'])
// 加载状态(请求验证码时)
const isLoading = ref(false)
// 是否正在倒计时
const isCountingDown = ref(false)
// 倒计时秒数
const countDown = ref(0)
// 倒计时定时器
let timer = null
// 获取验证码点击事件
const handleGetCaptcha = async () => {
// 倒计时中 / 加载中 / 禁用状态 禁止点击
if (isCountingDown.value || isLoading.value || props.disabled) return
try {
// 开启加载状态
isLoading.value = true
// 触发父组件的请求方法(真正的接口请求写在父组件)
await getSms({ type: props.type });
ElNotification.success({
title: '成功',
message: '验证码已发送,请注意查收',
});
// ======================
// 请求成功 → 开始倒计时
// ======================
startCountDown()
} catch (error) {
// 请求失败 → 不触发倒计时,控制台提示
console.error('', error)
} finally {
// 关闭加载状态
setTimeout(() => {
isLoading.value = false
}, 500) // 适当延迟,避免闪烁
}
}
// 倒计时核心逻辑
const startCountDown = () => {
// 初始化倒计时时间
countDown.value = props.countDownNum
isCountingDown.value = true
// 开启定时器
timer = setInterval(() => {
countDown.value--
// 倒计时结束
if (countDown.value <= 0) {
clearInterval(timer)
timer = null
isCountingDown.value = false
}
}, 1000)
}
// 页面销毁时清除定时器(防止内存泄漏)
onUnmounted(() => {
if (timer) clearInterval(timer)
})
</script>
<style scoped>
/* 你可以在这里自定义按钮默认样式,也可以在父组件覆盖 */
.captcha-btn {
min-width: 120px;
}
</style>