ECS-Vue/src/views/auth/Login.vue
2025-02-18 14:02:00 +08:00

342 lines
6.8 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>
<transition name="fade" mode="out-in">
<div class="login-container">
<el-card class="login-box">
<h2>登录系统</h2>
<el-form
@submit.prevent="handleLogin"
:model="loginForm"
:rules="rules"
ref="loginForm"
>
<el-row class="form-item">
<el-col :span="6" class="label-col">
<label>用户名</label>
</el-col>
<el-col :span="14">
<el-input
v-model="loginForm.username"
placeholder="请输入用户名"
@keyup.enter="handleLogin"
></el-input>
</el-col>
</el-row>
<el-row class="form-item">
<el-col :span="6" class="label-col">
<label>密码:</label>
</el-col>
<el-col :span="14">
<el-input
type="password"
v-model="loginForm.password"
placeholder="请输入密码"
@keyup.enter="handleLogin"
show-password
></el-input>
</el-col>
</el-row>
<el-button
type="primary"
@click="handleLogin"
class="submit-btn"
:class="{ 'button-loading': loading }"
@mouseenter="buttonHover = true"
@mouseleave="buttonHover = false"
>
<span class="button-text" :class="{ 'text-loading': loading }">
{{ loading ? '登录中...' : '登录' }}
</span>
<span class="button-effect"></span>
</el-button>
</el-form>
<div class="form-footer">
<p>还没有账号?
<router-link to="/register" class="link-btn">
立即注册
<span class="arrow"></span>
</router-link>
</p>
</div>
</el-card>
</div>
</transition>
</template>
<script>
export default {
name: 'LoginPage',
data () {
return {
loginForm: {
username: '',
password: ''
},
rules: {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 3, max: 20, message: '长度在 3 到 20 个字符', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 6, max: 20, message: '长度在 6 到 20 个字符', trigger: 'blur' }
]
},
loading: false,
buttonHover: false
}
},
methods: {
handleLogin () {
if (this.loading) return
this.$refs.loginForm.validate((valid) => {
if (valid) {
this.loading = true
console.log('登录信息:', this.loginForm)
// 模拟登录请求
setTimeout(() => {
this.loading = false
this.$message.success('登录成功')
}, 2000)
} else {
return false
}
})
}
}
}
</script>
<style scoped>
.login-container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background: linear-gradient(135deg, #1abc9c 0%, #8e44ad 100%);
position: relative;
overflow: hidden;
}
.login-container::before {
content: '';
position: absolute;
width: 2000px;
height: 2000px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.1);
top: -10%;
right: 48%;
transform: translateY(-50%);
animation: float 6s ease-in-out infinite;
}
.login-container::after {
content: '';
position: absolute;
width: 1500px;
height: 1500px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.1);
top: -10%;
right: 52%;
transform: translateY(-50%);
animation: float 8s ease-in-out infinite;
}
.login-box {
width: 500px;
backdrop-filter: blur(10px);
border: 1px solid rgba(255,255,255,0.2);
position: relative;
z-index: 1;
transform-origin: center center;
perspective: 1000px;
}
:deep(.el-card__body) {
padding: 30px;
backface-visibility: hidden;
}
h2 {
text-align: center;
margin-bottom: 30px;
color: #2c3e50;
}
.form-item {
margin-bottom: 20px;
display: flex;
align-items: center;
position: relative;
}
.label-col {
text-align: right;
padding-right: 20px;
line-height: 40px;
color: #606266;
font-weight: 500;
transition: all 0.3s ease;
}
.form-item:hover .label-col {
color: #409EFF;
}
.submit-btn {
width: 60%;
margin-top: 20px;
position: relative;
overflow: hidden;
transition: all 0.3s ease;
height: 40px;
border: none;
}
.submit-btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
}
.submit-btn:active {
transform: translateY(0);
}
.button-text {
position: relative;
z-index: 1;
transition: all 0.3s ease;
}
.button-effect {
position: absolute;
top: 50%;
left: 50%;
width: 0;
height: 0;
background: rgba(255,255,255,0.2);
border-radius: 50%;
transform: translate(-50%, -50%);
transition: all 0.5s ease;
}
.submit-btn:hover .button-effect {
width: 300px;
height: 300px;
}
.button-loading {
background: #409EFF !important;
cursor: wait;
}
.text-loading {
animation: textLoading 1.5s infinite;
}
@keyframes textLoading {
0% { opacity: 1; }
50% { opacity: 0.5; }
100% { opacity: 1; }
}
.form-footer {
margin-top: 20px;
text-align: center;
}
.form-footer a {
color: #409EFF;
text-decoration: none;
position: relative;
padding-right: 24px;
transition: all 0.3s ease;
}
.link-btn {
display: inline-flex;
align-items: center;
}
.arrow {
position: absolute;
right: 0;
opacity: 0;
transform: translateX(-8px);
transition: all 0.3s ease;
}
.link-btn:hover {
padding-right: 28px;
}
.link-btn:hover .arrow {
opacity: 1;
transform: translateX(0);
}
@keyframes float {
0% {
transform: translateY(-50%) rotate(0deg);
}
50% {
transform: translateY(-45%) rotate(180deg);
}
100% {
transform: translateY(-50%) rotate(360deg);
}
}
/* 页面过渡动画 */
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.3s ease, transform 0.3s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
transform: translateX(-30px);
}
.fade-enter-to,
.fade-leave-from {
opacity: 1;
transform: translateX(0);
}
.el-input {
transition: all 0.3s ease;
}
.el-input:focus-within {
transform: translateX(5px);
}
/* 添加输入框焦点时的装饰线 */
.el-input:focus-within::after {
content: '';
position: absolute;
left: -10px;
top: 50%;
height: 60%;
width: 3px;
background: #409EFF;
transform: translateY(-50%);
border-radius: 3px;
animation: focusLine 0.3s ease;
}
@keyframes focusLine {
from {
opacity: 0;
transform: translateY(-50%) scaleY(0);
}
to {
opacity: 1;
transform: translateY(-50%) scaleY(1);
}
}
</style>