202 lines
4.5 KiB
Vue
202 lines
4.5 KiB
Vue
<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>
|
||
|