登录表单校验代码重构
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, password: string,
//手机号 //手机号
phone: string, // phone: string,
//手机验证码
//mobileCode: string
}
export interface phoneLoginRequestData {
//手机号
phone: string,
//手机验证码 //手机验证码
mobileCode: string mobileCode: string
} }
export interface forgetRequestData { export interface forgetRequestData {
/** admin 或 editor */ /** admin 或 editor */
username: string // username: string
/** 密码 */ /** 密码 */
password: string, password: string,
//确认密码 //确认密码

View File

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

View File

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