Vue.js+Element UI 登录界面开发详解【附源码】

成果图:


一、技术架构解析

本登录模块采用前后端分离架构,前端基于Vue.js+Element UI实现交互逻辑,主要包含以下技术要点:

  1. 组件化开发 - 采用单文件组件形式组织代码
  2. 响应式设计 - 实现多终端适配
  3. 状态管理 - 使用sessionStorage维护会话状态
  4. 安全验证 - 前后端双重表单校验机制

二、核心实现原理

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路径
相关推荐
kyriewen5 分钟前
我上手了 Vite+ 1.0:Node 不用自己装,lint 却翻车了
前端·javascript·程序员
松就是我902987 分钟前
你的 PPT 不缺内容,缺一个讲它的人
前端
松就是我902989 分钟前
别再熬夜做 PPT 了!输入一个主题,AI 帮你把整套幻灯片做好,还能随便改字
前端
吴凡wudianmei11 分钟前
每调一次模型都花钱?如何用工程手段把调用压到最少?
前端·后端·架构
李元_霸12 分钟前
基于 AI 的 Web 与 App 端到端测试实践
前端·人工智能
欣欣之王来了17 分钟前
Vue3项目脚手架:Vite vs Vue CLI怎么选?
前端·学习·架构·项目·vue3教程
用户27886072856730 分钟前
别把 tool.completed 当成业务成功:AI 工具权限审计的四层事件链
前端
陆柒14534 分钟前
跟着 Webpack 配置学习前端工程化
前端
用户63533002547940 分钟前
Day 1|HTML5:一个商城首页的骨架,从 DOCTYPE 到语义化
前端
平凡的阿泽1 小时前
我用 Trae 实现了AI辩论赛
前端