Skip to content

Commit b1cb980

Browse files
committed
refactor!: 重构登录页面
1 parent 6258eec commit b1cb980

File tree

6 files changed

+500
-384
lines changed

6 files changed

+500
-384
lines changed

src/components/LoginForm/index.vue

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
<script setup lang="ts">
2+
import type { FormInstance, FormRules } from 'element-plus'
3+
import useUserStore from '@/store/modules/user'
4+
5+
defineOptions({
6+
name: 'LoginForm',
7+
})
8+
9+
const props = defineProps<{
10+
account?: string
11+
}>()
12+
13+
const emits = defineEmits<{
14+
onLogin: [account: string]
15+
onRegister: [account: string]
16+
onResetPassword: [account: string]
17+
}>()
18+
19+
const userStore = useUserStore()
20+
21+
const title = import.meta.env.VITE_APP_TITLE
22+
const loading = ref(false)
23+
24+
// 登录方式,default 账号密码登录,qrcode 扫码登录
25+
const type = ref('default')
26+
const formRef = ref<FormInstance>()
27+
const form = ref({
28+
account: props.account ?? localStorage.login_account ?? '',
29+
password: '',
30+
remember: !!localStorage.login_account,
31+
})
32+
const rules = ref<FormRules>({
33+
account: [
34+
{ required: true, trigger: 'blur', message: '请输入用户名' },
35+
],
36+
password: [
37+
{ required: true, trigger: 'blur', message: '请输入密码' },
38+
{ min: 6, max: 18, trigger: 'blur', message: '密码长度为6到18位' },
39+
],
40+
})
41+
function handleLogin() {
42+
formRef.value?.validate((valid) => {
43+
if (valid) {
44+
loading.value = true
45+
userStore.login(form.value).then(() => {
46+
if (form.value.remember) {
47+
localStorage.setItem('login_account', form.value.account)
48+
}
49+
else {
50+
localStorage.removeItem('login_account')
51+
}
52+
emits('onLogin', form.value.account)
53+
}).finally(() => {
54+
loading.value = false
55+
})
56+
}
57+
})
58+
}
59+
60+
function testAccount(account: string) {
61+
form.value.account = account
62+
form.value.password = '123456'
63+
handleLogin()
64+
}
65+
</script>
66+
67+
<template>
68+
<ElForm ref="formRef" :model="form" :rules="rules" class="min-h-500px w-full flex-col-stretch-center p-12">
69+
<div class="mb-6">
70+
<HTabList
71+
v-model="type" :options="[
72+
{ label: '账号密码登录', value: 'default' },
73+
{ label: '扫码登录', value: 'qrcode' },
74+
]"
75+
/>
76+
</div>
77+
<template v-if="type === 'default'">
78+
<h3 class="mb-8 text-xl color-[var(--el-text-color-primary)] font-bold">
79+
欢迎使用 {{ title }} ! 👋🏻
80+
</h3>
81+
<div>
82+
<ElFormItem prop="account">
83+
<ElInput v-model="form.account" placeholder="用户名" type="text" tabindex="1">
84+
<template #prefix>
85+
<SvgIcon name="i-ri:user-3-fill" />
86+
</template>
87+
</ElInput>
88+
</ElFormItem>
89+
<ElFormItem prop="password">
90+
<ElInput v-model="form.password" type="password" placeholder="密码" tabindex="2" show-password @keyup.enter="handleLogin">
91+
<template #prefix>
92+
<SvgIcon name="i-ri:lock-2-fill" />
93+
</template>
94+
</ElInput>
95+
</ElFormItem>
96+
</div>
97+
<div class="mb-4 flex-center-between">
98+
<ElCheckbox v-model="form.remember">
99+
记住我
100+
</ElCheckbox>
101+
<ElLink type="primary" :underline="false" @click="emits('onResetPassword', form.account)">
102+
忘记密码了?
103+
</ElLink>
104+
</div>
105+
<ElButton :loading="loading" type="primary" size="large" style="width: 100%;" @click.prevent="handleLogin">
106+
登录
107+
</ElButton>
108+
<div class="mt-4 flex-center gap-2 text-sm color-[var(--el-text-color-secondary)]">
109+
还没有帐号?
110+
<ElLink type="primary" :underline="false" @click="emits('onRegister', form.account)">
111+
创建新帐号
112+
</ElLink>
113+
</div>
114+
</template>
115+
<template v-else-if="type === 'qrcode'">
116+
<div class="flex-col-center">
117+
<el-image src="https://s2.loli.net/2024/04/26/GsahtuIZ9XOg5jr.png" class="h-[250px] w-[250px]" />
118+
<div class="mt-2 op-50">
119+
请使用微信扫码登录
120+
</div>
121+
</div>
122+
</template>
123+
<div class="mt-4 text-center -mb-4">
124+
<ElDivider>演示账号一键登录</ElDivider>
125+
<ElButton type="primary" size="small" plain @click="testAccount('admin')">
126+
admin
127+
</ElButton>
128+
<ElButton size="small" plain @click="testAccount('test')">
129+
test
130+
</ElButton>
131+
</div>
132+
</ElForm>
133+
</template>
134+
135+
<style lang="scss" scoped>
136+
:deep(input[type="password"]::-ms-reveal) {
137+
display: none;
138+
}
139+
140+
.el-form-item {
141+
margin-bottom: 24px;
142+
143+
:deep(.el-input) {
144+
width: 100%;
145+
height: 48px;
146+
line-height: inherit;
147+
148+
input {
149+
height: 48px;
150+
}
151+
152+
.el-input__prefix,
153+
.el-input__suffix {
154+
display: flex;
155+
align-items: center;
156+
}
157+
158+
.el-input__prefix {
159+
left: 10px;
160+
}
161+
162+
.el-input__suffix {
163+
right: 10px;
164+
}
165+
}
166+
}
167+
168+
:deep(.el-divider__text) {
169+
white-space: nowrap;
170+
background-color: var(--g-container-bg);
171+
}
172+
</style>
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
<script setup lang="ts">
2+
import type { FormInstance, FormRules } from 'element-plus'
3+
import { ElMessage } from 'element-plus'
4+
5+
defineOptions({
6+
name: 'RegisterForm',
7+
})
8+
9+
const props = defineProps<{
10+
account?: string
11+
}>()
12+
13+
const emits = defineEmits<{
14+
onLogin: [account: string]
15+
onRegister: [account: string]
16+
}>()
17+
18+
const loading = ref(false)
19+
20+
const formRef = ref<FormInstance>()
21+
const form = ref({
22+
account: props.account ?? '',
23+
captcha: '',
24+
password: '',
25+
checkPassword: '',
26+
})
27+
const rules = ref<FormRules>({
28+
account: [
29+
{ required: true, trigger: 'blur', message: '请输入用户名' },
30+
],
31+
captcha: [
32+
{ required: true, trigger: 'blur', message: () => '请输入验证码' },
33+
],
34+
password: [
35+
{ required: true, trigger: 'blur', message: '请输入密码' },
36+
{ min: 6, max: 18, trigger: 'blur', message: '密码长度为6到18位' },
37+
],
38+
checkPassword: [
39+
{ required: true, trigger: 'blur', message: '请再次输入密码' },
40+
{
41+
validator: (rule, value, callback) => {
42+
if (value !== form.value.password) {
43+
callback(new Error('两次输入的密码不一致'))
44+
}
45+
else {
46+
callback()
47+
}
48+
},
49+
},
50+
],
51+
})
52+
function handleRegister() {
53+
ElMessage({
54+
message: '注册模块仅提供界面演示,无实际功能,需开发者自行扩展',
55+
type: 'warning',
56+
})
57+
formRef.value?.validate((valid) => {
58+
if (valid) {
59+
// 这里编写业务代码
60+
emits('onRegister', form.value.account)
61+
}
62+
})
63+
}
64+
</script>
65+
66+
<template>
67+
<ElForm ref="formRef" :model="form" :rules="rules" class="min-h-500px w-full flex-col-stretch-center p-12">
68+
<h3 class="mb-8 text-xl color-[var(--el-text-color-primary)] font-bold">
69+
探索从这里开始! 🚀
70+
</h3>
71+
<div>
72+
<ElFormItem prop="account">
73+
<ElInput v-model="form.account" placeholder="用户名" tabindex="1">
74+
<template #prefix>
75+
<SvgIcon name="i-ri:user-3-fill" />
76+
</template>
77+
</ElInput>
78+
</ElFormItem>
79+
<ElFormItem prop="captcha">
80+
<ElInput v-model="form.captcha" placeholder="验证码" tabindex="2">
81+
<template #prefix>
82+
<SvgIcon name="i-ic:baseline-verified-user" />
83+
</template>
84+
<template #append>
85+
<ElButton>发送验证码</ElButton>
86+
</template>
87+
</ElInput>
88+
</ElFormItem>
89+
<ElFormItem prop="password">
90+
<ElInput v-model="form.password" type="password" placeholder="密码" tabindex="3" show-password>
91+
<template #prefix>
92+
<SvgIcon name="i-ri:lock-2-fill" />
93+
</template>
94+
</ElInput>
95+
</ElFormItem>
96+
<ElFormItem prop="checkPassword">
97+
<ElInput v-model="form.checkPassword" type="password" placeholder="确认密码" tabindex="4" show-password>
98+
<template #prefix>
99+
<SvgIcon name="i-ri:lock-2-fill" />
100+
</template>
101+
</ElInput>
102+
</ElFormItem>
103+
</div>
104+
<ElButton :loading="loading" type="primary" size="large" style="width: 100%; margin-top: 20px;" @click.prevent="handleRegister">
105+
注册
106+
</ElButton>
107+
<div class="mt-4 flex-center gap-2 text-sm color-[var(--el-text-color-secondary)]">
108+
已经有帐号?
109+
<ElLink type="primary" :underline="false" @click="emits('onLogin', form.account)">
110+
去登录
111+
</ElLink>
112+
</div>
113+
</ElForm>
114+
</template>
115+
116+
<style lang="scss" scoped>
117+
:deep(input[type="password"]::-ms-reveal) {
118+
display: none;
119+
}
120+
121+
.el-form-item {
122+
margin-bottom: 24px;
123+
124+
:deep(.el-input) {
125+
width: 100%;
126+
height: 48px;
127+
line-height: inherit;
128+
129+
input {
130+
height: 48px;
131+
}
132+
133+
.el-input__prefix,
134+
.el-input__suffix {
135+
display: flex;
136+
align-items: center;
137+
}
138+
139+
.el-input__prefix {
140+
left: 10px;
141+
}
142+
143+
.el-input__suffix {
144+
right: 10px;
145+
}
146+
}
147+
}
148+
</style>

0 commit comments

Comments
 (0)