Files
sbu4pe/src/components/authentication/LoginForm.vue
2025-08-13 01:55:49 +00:00

202 lines
4.5 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>
<el-form
ref="loginFormRef"
:model="loginForm"
:rules="loginRules"
class="login-form"
>
<el-form-item prop="username">
<el-input
v-model="loginForm.username"
:placeholder="$t('auth.usernamePlaceholder')"
>
<template #prefix>
<el-icon class="el-input__icon"><User /></el-icon>
</template>
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="loginForm.password"
:placeholder="$t('auth.passwordPlaceholder')"
type="password"
show-password
>
<template #prefix>
<el-icon class="el-input__icon"><Lock /></el-icon>
</template>
</el-input>
</el-form-item>
<!-- 合并记住我和登录按钮到同一行 -->
<el-form-item class="form-actions-row">
<div class="flex-container">
<!-- 记住我选项 -->
<div class="remember-me">
<el-checkbox v-model="rememberMe" :label="$t('auth.rememberMe')" class="remember-me-checkbox">
{{ $t('auth.rememberMe') }}
</el-checkbox>
</div>
<!-- 登录按钮 - 强制靠右 -->
<div class="button-spacer"></div>
<div class="button-wrapper">
<el-button
type="primary"
@click="handleSubmit"
>
{{ $t('auth.loginBtn') }}
</el-button>
</div>
</div>
</el-form-item>
</el-form>
</template>
<script setup>
import { ref, defineEmits, onMounted } from 'vue';
import { useI18n } from 'vue-i18n';
import { User, Lock } from '@element-plus/icons-vue';
// 表单数据
const loginForm = ref({
username: '',
password: ''
});
// 记住我选项
const rememberMe = ref(false);
// 表单引用
const loginFormRef = ref(null);
// 国际化
const { t } = useI18n();
// 添加props定义
const props = defineProps({
loading: {
type: Boolean,
default: false
}
});
// 初始化 - 检查是否有记住的登录信息
onMounted(() => {
const savedUser = localStorage.getItem('rememberedUser');
if (savedUser) {
try {
const userData = JSON.parse(savedUser);
loginForm.value.username = userData.username || '';
loginForm.value.password = userData.password || '';
rememberMe.value = true;
} catch (e) {
console.error('Failed to parse remembered user data', e);
localStorage.removeItem('rememberedUser');
}
}
});
// 表单验证规则
const loginRules = ref({
username: [
{ required: true, message: t('auth.username'), trigger: 'blur' },
{ min: 6, max: 12, message: t('auth.usernameRule'), trigger: 'blur' }
],
password: [
{ required: true, message: t('auth.password'), trigger: 'blur' },
{ min: 6, message: t('auth.passwordRule'), trigger: 'blur' }
]
});
// 定义事件
const emit = defineEmits(['submit-form']);
// 提交表单
const handleSubmit = () => {
loginFormRef.value.validate((valid) => {
if (valid) {
// 处理记住我功能
if (rememberMe.value) {
localStorage.setItem('rememberedUser', JSON.stringify({
username: loginForm.value.username,
password: loginForm.value.password
}));
} else {
localStorage.removeItem('rememberedUser');
}
emit('submit-form', { ...loginForm.value });
} else {
console.log('表单验证失败');
return false;
}
});
};
</script>
<style scoped>
.login-form {
width: 100%;
}
/* 关键使用flex容器并移除所有默认间距 */
.form-actions-row {
padding: 0 !important;
margin: 20px 0 0 0 !important;
}
/* 内部flex容器控制对齐 */
.flex-container {
display: flex;
width: 100%;
align-items: center;
}
/* 记住我选项靠左 */
.remember-me {
margin: 0;
padding: 0;
}
/* 记住我字体颜色设置 */
.remember-me-checkbox {
--el-checkbox-text-color: var(--color-text); /* 使用主题文本色 */
/* 或者使用自定义颜色:
--el-checkbox-text-color: #666; */
font-size: 14px; /* 可选:调整字体大小 */
}
/* 填充空间,将按钮推到右侧 */
.button-spacer {
flex-grow: 1;
}
/* 按钮容器确保按钮靠右 */
.button-wrapper {
margin: 0;
padding: 0;
display: flex;
justify-content: flex-end;
}
/* 按钮样式 */
.el-button {
width: 120px;
margin: 0 !important;
}
/* 强制覆盖Element Plus的默认样式 */
:deep(.el-form-item__content) {
margin: 0 !important;
padding: 0 !important;
width: 100% !important;
}
/* 图标样式 */
.el-input__icon {
font-size: 18px;
}
</style>