refactor: 抽离短信验证码倒计时 Composable 并拆分模块化 base.css 样式文件

This commit is contained in:
yml
2026-05-25 09:07:39 +08:00
parent 7a5d3cc425
commit 3a6e6e6a33
7 changed files with 1455 additions and 1495 deletions
+4 -58
View File
@@ -1,76 +1,22 @@
<script setup lang="ts">
import { onUnmounted, reactive, ref } from "vue";
import { reactive, ref } from "vue";
import { RouterLink, useRoute, useRouter } from "vue-router";
import { showToast, showDialog } from "vant";
import { sendSmsCode } from "@/api/auth";
import { useSessionStore } from "@/stores/session";
import { useSmsCountdown } from "@/composables/useSmsCountdown";
const router = useRouter();
const route = useRoute();
const session = useSessionStore();
const loading = ref(false);
const sending = ref(false);
const agreed = ref(false);
const form = reactive({
phone: "",
code: "",
});
const countDown = ref(0);
let timer: ReturnType<typeof setInterval> | null = null;
function startCountDown() {
countDown.value = 60;
timer = setInterval(() => {
countDown.value--;
if (countDown.value <= 0) {
clearInterval(timer!);
timer = null;
}
}, 1000);
}
onUnmounted(() => {
if (timer) {
clearInterval(timer);
timer = null;
}
});
/* --------- 业务方法 --------- */
async function handleSendCode() {
if (!form.phone.trim()) {
showToast({ message: "请输入手机号", icon: "warning-o" });
return;
}
sending.value = true;
try {
await sendSmsCode(form.phone);
showToast({
message: "验证码已发送,开发环境请查看后端日志",
icon: "passed",
});
startCountDown();
} catch (error) {
showToast({
message: readError(error, "验证码发送失败,请稍后重试"),
icon: "cross",
});
} finally {
sending.value = false;
}
}
function readError(error: unknown, fallback: string) {
if (typeof error === "object" && error && "response" in error) {
const response = (error as { response?: { data?: { message?: string } } })
.response;
return response?.data?.message || fallback;
}
return fallback;
}
const { countDown, sending, handleSendCode, readError } = useSmsCountdown();
async function handleLogin() {
if (!agreed.value) {
@@ -135,7 +81,7 @@ async function handleLogin() {
:disabled="sending || countDown > 0"
:loading="sending"
class="code-btn"
@click="handleSendCode"
@click="handleSendCode(form.phone)"
>
{{
countDown > 0
@@ -1,16 +1,15 @@
<script setup lang="ts">
import { onUnmounted, reactive, ref } from "vue";
import { reactive, ref } from "vue";
import { RouterLink, useRoute, useRouter } from "vue-router";
import { showToast } from "vant";
import { sendSmsCode } from "@/api/auth";
import { useSessionStore } from "@/stores/session";
import { useSmsCountdown } from "@/composables/useSmsCountdown";
const router = useRouter();
const route = useRoute();
const session = useSessionStore();
const loading = ref(false);
const sending = ref(false);
const agreed = ref(false);
const form = reactive({
phone: "",
@@ -18,61 +17,7 @@ const form = reactive({
inviteCode: "",
});
/* --------- 验证码倒计时 --------- */
const countDown = ref(0);
let timer: ReturnType<typeof setInterval> | null = null;
function startCountDown() {
countDown.value = 60;
timer = setInterval(() => {
countDown.value--;
if (countDown.value <= 0) {
clearInterval(timer!);
timer = null;
}
}, 1000);
}
onUnmounted(() => {
if (timer) {
clearInterval(timer);
timer = null;
}
});
/* --------- 业务方法 --------- */
async function handleSendCode() {
if (!form.phone.trim()) {
showToast({ message: "请输入手机号", icon: "warning-o" });
return;
}
sending.value = true;
try {
await sendSmsCode(form.phone);
showToast({
message: "验证码已发送,开发环境请查看后端日志",
icon: "passed",
});
startCountDown();
} catch (error) {
showToast({
message: readError(error, "验证码发送失败,请稍后重试"),
icon: "cross",
});
} finally {
sending.value = false;
}
}
function readError(error: unknown, fallback: string) {
if (typeof error === "object" && error && "response" in error) {
const response = (error as { response?: { data?: { message?: string } } })
.response;
return response?.data?.message || fallback;
}
return fallback;
}
const { countDown, sending, handleSendCode, readError } = useSmsCountdown();
async function handleRegister() {
if (!agreed.value) {
@@ -138,7 +83,7 @@ async function handleRegister() {
:disabled="sending || countDown > 0"
:loading="sending"
class="code-btn"
@click="handleSendCode"
@click="handleSendCode(form.phone)"
>
{{
countDown > 0