成果图:
一、技术架构解析
本登录模块采用前后端分离架构,前端基于Vue.js+Element UI实现交互逻辑,主要包含以下技术要点:
- 组件化开发 - 采用单文件组件形式组织代码
- 响应式设计 - 实现多终端适配
- 状态管理 - 使用sessionStorage维护会话状态
- 安全验证 - 前后端双重表单校验机制
二、核心实现原理
1. 数据驱动视图
通过Vue的响应式系统实现数据绑定:
data() {
return {
loginForm: {
username: '',
password: ''
}
}
}
- 表单输入与
loginForm
对象双向绑定 - 数据变更自动触发视图更新
2. 表单验证机制
rules: {
username: [
{ required: true, message: '请输入用户名' },
{ min: 3, max: 20, message: '长度3-20字符' }
]
}
- 实时校验输入合法性
- 支持多种验证类型(必填、长度、正则等)
3. 登录流程控制
this.$axios.post('/user/login', loginData)
.then(res => {
sessionStorage.setItem("CurUser", JSON.stringify(res.data.user));
this.$router.replace('/Index');
})
- 使用axios发送POST请求
- 会话存储采用sessionStorage
- 路由跳转通过Vue Router实现
三、关键技术点详解
1. 防重复提交设计
confirm_disabled: false, // 状态控制
// 请求开始
this.confirm_disabled = true;
// 请求结束
.finally(() => {
this.confirm_disabled = false;
})
- 按钮禁用状态联动
- 确保请求生命周期控制
2. 异常处理机制
.catch(error => {
this.$message.error('服务器连接异常');
})
- 网络异常统一处理
- Element UI消息提示组件
3. 路由守卫集成
this.$router.replace('/Index');
- 登录成功替换当前路由
- 避免回退到登录页
四、完整代码
<template>
<div class="loginBody">
<div style="width:97%;text-align:center;color:white;padding: 100px 100px 0 0;font-size:22px;">
<h1>新能源汽车充电监管系统</h1>
</div>
<div class="loginDiv">
<div class="login-content">
<h1 class="login-title">用户登录</h1>
<el-form :model="loginForm" label-width="100px" :rules="rules" ref="loginForm" style="margin-left: 10px">
<el-form-item label="用户名" prop="username">
<el-input style="width: 200px" type="text" v-model="loginForm.username"
autocomplete="off" size="medium"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input style="width: 200px" type="password" v-model="loginForm.password"
show-password autocomplete="off" size="medium" @keyup.enter.native="confirm"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" size="medium" @click="confirm" :disabled="confirm_disabled">登 录</el-button>
<el-button type="primary" size="medium" @click="$router.push('/Register')" style="margin-left: 50px">注 册</el-button>
</el-form-item>
</el-form>
</div>
</div>
</div>
</template>
<script>
export default {
name: "Login",
data() {
return {
confirm_disabled: false,
loginForm: {
username: '', // 字段名改为username
password: ''
},
rules: {
username: [ // 对应字段修改
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 3, max: 20, message: '长度在3到20个字符', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' }
]
}
}
},
methods: {
confirm() {
this.confirm_disabled = true;
this.$refs.loginForm.validate((valid) => {
if (valid) {
// 构造符合新接口要求的请求体
const loginData = {
username: this.loginForm.username,
password: this.loginForm.password
};
this.$axios.post(this.$httpUrl + '/user/login', loginData)
.then(res => res.data)
.then(res => {
if (res.code === 200) {
// 存储用户信息(根据实际返回数据结构调整)
sessionStorage.setItem("CurUser", JSON.stringify(res.data.user));
// 跳转前显示欢迎提示
this.$message.success(`欢迎回来,${res.data.user.realName || ''}!`);
this.$router.replace('/Index');
} else {
this.$message.error(res.msg || '登录失败,请检查用户名和密码');
}
})
.catch(error => {
console.error('登录请求错误:', error);
this.$message.error('服务器连接异常');
})
.finally(() => {
this.confirm_disabled = false;
});
} else {
this.confirm_disabled = false;
return false;
}
});
}
}
}
</script>
<style scoped>
/* 保持原有样式不变 */
.loginBody {
position: absolute;
width: 100%;
height: 100%;
background: url('../assets/home.jpg');
background-size: cover;
overflow-x: hidden;
}
.loginDiv {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 450px;
height: 330px;
background: rgba(255, 255, 255, 0.95);
border-radius: 15px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
.login-title {
margin: 20px 0;
text-align: center;
color: #303133;
}
.login-content {
padding: 25px;
}
</style>
五、开发注意事项
环境配置
- 安装Element UI:
npm install element-ui
- 配置axios:需在main.js中全局引入
接口对接
- 修改$httpUrl为实际后端地址
- 根据实际API响应结构调整res.data.data.user路径