Files
aiot-uniapp/src/pages/auth/components/code-input.vue

91 lines
2.3 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>
<view class="input-item">
<wd-icon name="lock-on" size="20px" color="#1890ff" />
<wd-input
:model-value="modelValue"
placeholder="请输入验证码"
clearable
clear-trigger="focus"
no-border
type="number"
:maxlength="6"
@update:model-value="$emit('update:modelValue', $event)"
/>
<view
class="whitespace-nowrap border-l-1rpx border-l-[#e5e5e5] border-l-solid px-20rpx text-28rpx text-[#1890ff]"
@click="handleSendCode"
>
<text :class="{ 'text-gray-400': countdown > 0 }">
{{ countdown > 0 ? `${countdown} 秒后重发` : "获取验证码" }}
</text>
</view>
</view>
</template>
<script lang="ts" setup>
import { onUnmounted, ref } from "vue";
import { useToast } from "wot-design-uni";
import { sendSmsCode } from "@/api/login";
import { isMobile } from "@/utils/validator";
defineOptions({
name: "CodeInput",
});
const props = defineProps<{
modelValue: string; // 验证码值 (v-model)
mobile: string; // 手机号
scene: number; // 短信场景21-登录 23-重置密码
beforeSend?: () => boolean; // 发送前的校验函数,返回 false 则不发送
}>();
defineEmits<{
"update:modelValue": [value: string];
}>();
const toast = useToast();
const countdown = ref(0); // 验证码倒计时,单位秒
let countdownTimer: ReturnType<typeof setInterval> | null = null; // 倒计时定时器
/** 页面卸载时清除倒计时定时器 */
onUnmounted(() => {
if (countdownTimer) {
clearInterval(countdownTimer);
countdownTimer = null;
}
});
/** 发送验证码 */
async function handleSendCode() {
// 执行前置校验
if (props.beforeSend && !props.beforeSend()) {
return;
}
if (countdown.value > 0) {
return;
}
if (!props.mobile) {
toast.warning("请输入手机号");
return;
}
if (!isMobile(props.mobile)) {
toast.warning("请输入正确的手机号");
return;
}
// 发送验证码
await sendSmsCode({ mobile: props.mobile, scene: props.scene });
toast.success("验证码已发送");
// 开始倒计时
countdown.value = 60;
countdownTimer = setInterval(() => {
countdown.value--;
if (countdown.value <= 0) {
clearInterval(countdownTimer!);
countdownTimer = null;
}
}, 1000);
}
</script>