登录表单校验代码重构
Some checks failed
Build And Deploy v3-admin-vite / build-and-deploy (push) Has been cancelled

This commit is contained in:
吕杰刚 2025-05-07 23:30:22 +08:00
parent e12f4cc9e9
commit 158f6fccd9
3 changed files with 138 additions and 60 deletions

View File

@ -4,14 +4,21 @@ export interface LoginRequestData {
/** 密码 */
password: string,
//手机号
phone: string,
// phone: string,
//手机验证码
//mobileCode: string
}
export interface phoneLoginRequestData {
//手机号
phone: string,
//手机验证码
mobileCode: string
}
export interface forgetRequestData {
/** admin 或 editor */
username: string
// username: string
/** 密码 */
password: string,
//确认密码

View File

@ -1,6 +1,10 @@
<script lang="ts" setup>
import type { FormInstance, FormRules } from "element-plus";
import type { LoginRequestData, forgetRequestData } from "./apis/type";
import type {
LoginRequestData,
forgetRequestData,
phoneLoginRequestData,
} from "./apis/type";
import { useSettingsStore } from "@/pinia/stores/settings";
import { useUserStore } from "@/pinia/stores/user";
import ThemeSwitch from "@@/components/ThemeSwitch/index.vue";
@ -8,7 +12,7 @@ import { Lock, User, Iphone, Promotion, Check } from "@element-plus/icons-vue";
import { loginApi } from "./apis";
import Owl from "./components/Owl.vue";
import { useFocus } from "./composables/useFocus";
import { reactive, ref } from "vue";
const router = useRouter();
const userStore = useUserStore();
@ -34,6 +38,10 @@ let isForgetPwd = ref(false);
const loginFormData: LoginRequestData = reactive({
username: "",
password: "",
});
/** 短信登录表单数据 */
const phoneFormData: phoneLoginRequestData = reactive({
phone: "",
mobileCode: "",
});
@ -51,23 +59,47 @@ const forgetFormData: forgetRequestData = reactive({
mobileCode: "",
});
// const loginFormRules: FormRules = {
// username: [{ required: true, message: "", trigger: "blur" }],
// password: [
// { required: true, message: "", trigger: "blur" },
// { min: 8, max: 16, message: " 8 16 ", trigger: "blur" },
// ],
// mobileCode: [
// { required: true, message: "", trigger: "blur" },
// ],
// phone: [
// { required: true, message: "", trigger: "blur" },
// { min: 4, max: 4, message: "", trigger: "blur" },
// ],
// };
/** 登录表单校验规则 */
const loginFormRules: FormRules = {
const loginFormRules = reactive<FormRules<LoginRequestData>>({
username: [{ required: true, message: "请输入用户名", trigger: "blur" }],
password: [
{ required: true, message: "请输入密码", trigger: "blur" },
{ min: 8, max: 16, message: "长度在 8 到 16 个字符", trigger: "blur" },
],
mobileCode: [
{ required: true, message: "请输入手机验证码", trigger: "blur" },
],
});
/** 登录表单校验规则 */
const phoneFormRules = reactive<FormRules<phoneLoginRequestData>>({
phone: [
{ required: true, message: "请输入手机号", trigger: "blur" },
{ min: 4, max: 4, message: "请检查验证码是否正确!", trigger: "blur" },
{ min: 11, max: 11, message: "请检查手机号是否正确!", trigger: "blur" },
],
};
mobileCode: [
{ required: true, message: "请输入手机验证码", trigger: "blur" },
{
min: 4,
max: 4,
message: "请检查手机验证码是否正确!",
trigger: "blur",
},
],
});
//
const forgetFormRules: FormRules = {
const forgetFormRules = reactive<FormRules<forgetRequestData>>({
phone: [
{ required: true, message: "请输入手机号 ", trigger: "blur" },
{
@ -126,28 +158,49 @@ const forgetFormRules: FormRules = {
trigger: "blur",
},
],
};
});
/** 登录 */
function handleLogin() {
loginFormRef.value?.validate((valid) => {
if (!valid) {
async function handleLogin(formEl) {
if (!formEl) return;
await formEl.validate((valid, fields) => {
if (valid) {
loading.value = true;
loginApi(loginFormData)
.then(({ data }) => {
console.log(data);
userStore.setToken(data.token);
router.push("/");
})
.catch(() => {
loginFormData.password = "";
})
.finally(() => {
loading.value = false;
});
} else {
ElMessage.error("表单校验不通过");
return;
}
loading.value = true;
loginApi(loginFormData)
.then(({ data }) => {
console.log(data);
userStore.setToken(data.token);
router.push("/");
})
.catch(() => {
loginFormData.password = "";
})
.finally(() => {
loading.value = false;
});
});
// loginFormRef.value?.validate((valid) => {
// if (!valid) {
// ElMessage.error("");
// return;
// }
// loading.value = true;
// loginApi(loginFormData)
// .then(({ data }) => {
// console.log(data);
// userStore.setToken(data.token);
// router.push("/");
// })
// .catch(() => {
// loginFormData.password = "";
// })
// .finally(() => {
// loading.value = false;
// });
// });
}
// true false
@ -219,36 +272,44 @@ watch(isDisabled, (newVal, oldVal) => {
@focus="handleFocus"
/>
</el-form-item>
<el-form-item prop="phone" v-show="!loginMethod">
<el-input
v-model.trim="loginFormData.phone"
placeholder="手机号"
tabindex="3"
:prefix-icon="Iphone"
size="large"
maxlength="11"
/>
</el-form-item>
<el-form-item prop="mobileCode" v-show="!loginMethod">
<el-input
v-model.trim="loginFormData.mobileCode"
placeholder="手机验证码"
tabindex="4"
:prefix-icon="Promotion"
size="large"
@blur="handleBlur"
@focus="handleFocus"
maxlength="4"
/>
<button
id="sendCode"
@click="getMobileCode(loginFormData.mobileCode)"
:disabled="isDisabled"
>
<span v-if="!isDisabled">获取验证码</span>
<span v-if="isDisabled">{{ countdown + " 秒后重试" }}</span>
</button>
</el-form-item>
<el-form
v-show="!loginMethod"
ref="phoneFormRef"
:model="phoneFormData"
:rules="phoneFormRules"
@keyup.enter="handleLogin"
><el-form-item prop="phone">
<el-input
v-model.trim="phoneFormData.phone"
placeholder="手机号"
tabindex="3"
:prefix-icon="Iphone"
size="large"
maxlength="11"
/>
</el-form-item>
<el-form-item prop="mobileCode" v-show="!loginMethod">
<el-input
v-model.trim="phoneFormData.mobileCode"
placeholder="手机验证码"
tabindex="4"
:prefix-icon="Promotion"
size="large"
@blur="handleBlur"
@focus="handleFocus"
maxlength="4"
/>
<button
id="sendCode"
@click="getMobileCode(phoneFormData.mobileCode)"
:disabled="isDisabled"
>
<span v-if="!isDisabled">获取验证码</span>
<span v-if="isDisabled">{{ countdown + " 秒后重试" }}</span>
</button>
</el-form-item></el-form
>
<!-- <el-form-item prop="code">
<el-input
v-model.trim="loginFormData.code"
@ -281,7 +342,7 @@ watch(isDisabled, (newVal, oldVal) => {
:loading="loading"
type="primary"
size="large"
@click.prevent="handleLogin"
@click.prevent="handleLogin(loginFormRef)"
>
</el-button>
@ -298,7 +359,7 @@ watch(isDisabled, (newVal, oldVal) => {
</div>
<div class="forget-content" v-if="isForgetPwd">
<el-form
ref="loginFormRef"
ref="forgetFormRef"
:model="forgetFormData"
:rules="forgetFormRules"
>

View File

@ -8,6 +8,7 @@ export {}
/* prettier-ignore */
declare module 'vue' {
export interface GlobalComponents {
ElAlert: typeof import('element-plus/es')['ElAlert']
ElAside: typeof import('element-plus/es')['ElAside']
ElAvatar: typeof import('element-plus/es')['ElAvatar']
ElBacktop: typeof import('element-plus/es')['ElBacktop']
@ -18,6 +19,7 @@ declare module 'vue' {
ElCard: typeof import('element-plus/es')['ElCard']
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
ElContainer: typeof import('element-plus/es')['ElContainer']
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
ElDialog: typeof import('element-plus/es')['ElDialog']
ElDivider: typeof import('element-plus/es')['ElDivider']
ElDrawer: typeof import('element-plus/es')['ElDrawer']
@ -35,10 +37,15 @@ declare module 'vue' {
ElMain: typeof import('element-plus/es')['ElMain']
ElMenu: typeof import('element-plus/es')['ElMenu']
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
ElOption: typeof import('element-plus/es')['ElOption']
ElPagination: typeof import('element-plus/es')['ElPagination']
ElPopover: typeof import('element-plus/es')['ElPopover']
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
ElSelect: typeof import('element-plus/es')['ElSelect']
ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
ElSwitch: typeof import('element-plus/es')['ElSwitch']
ElTable: typeof import('element-plus/es')['ElTable']
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
ElTabPane: typeof import('element-plus/es')['ElTabPane']
ElTabs: typeof import('element-plus/es')['ElTabs']
ElTag: typeof import('element-plus/es')['ElTag']
@ -46,4 +53,7 @@ declare module 'vue' {
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
}
export interface ComponentCustomProperties {
vLoading: typeof import('element-plus/es')['ElLoadingDirective']
}
}