首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >八、Vue3开发登录注册页面

八、Vue3开发登录注册页面

作者头像
程序员三明治
发布2025-12-18 19:56:53
发布2025-12-18 19:56:53
1700
举报
文章被收录于专栏:码力up码力up

前后端基础数据修改

在employee表中加三个权限相关的字段

image.png
image.png

给Employee实体类加属性以及set,get方法 在mapper文件的新增和更新操作上进行修改 前端页面的表单上加上账号列 在新增的时候,我们需要做一个表单的校验,如果账号没填就点保存是保存不了的。

如何做表单的校验?

在表单上加上ref

image.png
image.png

引入ref

image.png
image.png

改造保存按钮调用的save方法

代码语言:javascript
复制
const save = () => {
  formRef.value.validate((valid) => {
    if (valid) {
      data.form.id ? update() : add();
    }
  })
  data.form.id ? update() : add();
}

绑定规则

在data里定义rules

代码语言:javascript
复制
  rules: {
    username : [
      {required : true, message : '请输入账号', trigger : 'blur'}
    ],
    name : [
      {required : true, message : '请输入名称', trigger : 'blur'}
    ],
    no : [
      {required : true, message : '请输入工号', trigger : 'blur'}
    ]
  }

另外rules的username是需要和对话框表单的prop对应起来,例如:

此时我们测试发现 关闭对话框后再打开,没有清空选项,如图

如何关闭后清空选项?(也就是打开一个新的、无污染的对话框)

需要在dialog对话框上添加destroy-on-close即可实现

image.png
image.png

开发登录注册

登录

前端处理

Login.vue页面

代码语言:javascript
复制
<template>
  <div>
    <div class="login-container">
      <div class="login-box">
        <div style="padding: 50px 30px; background-color: white; border-radius: 5px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.5)">
          <el-form ref="formRef" :rules="data.rules" :model="data.form" style="width: 400px">
            <div style="margin-bottom: 30px; font-size: 25px; color: blue; font-weight: bold; text-align: center">欢迎登录后台管理系统</div>
            <el-form-item label="账号:" prop="username">
              <el-input size="large" v-model="data.form.username" placeholder="请输入账号"
                prefix-icon="User"></el-input>
            </el-form-item>
            <el-form-item label="密码:" prop="password">
              <el-input size="large" v-model="data.form.password" placeholder="请输入密码" prefix-icon="Lock" show-password></el-input>
            </el-form-item>
            <div style="margin-bottom: 20px">
              <el-button size="large" type="primary" style="width: 100%" @click="login">登录</el-button>
            </div>
            <div style="text-align: right">
              还没有账号?请<a href="/register" style="color: #909399; text-decoration: none"> 注册</a>
            </div>
          </el-form>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
  import { reactive,ref } from "vue";
  import { User, Lock } from "@element-plus/icons-vue"
  import request from "@/utils/request.js";
  import {ElMessage} from "element-plus";

  const data = reactive({
    form:{},
    rules :{
      username: [
        { required: true, message: "请输入账号", trigger: "blur" }
      ],
      password: [
        { required: true, message: "请输入密码", trigger: "blur" }
      ]
    }
  })

  const formRef = ref()

  const login = () => {
    formRef.value.validate(valid => {
      if (valid) {
        request.post("/login", data.form).then(res => {
          if (res.code === '200') {
            // 存储后台返回的用户数据信息
            localStorage.setItem("user", JSON.stringify(res.data)) // 把json对象转换成json字符串存储
            console.log(res.data)
            ElMessage.success('登录成功')
            location.href='/home'
          } else {
            ElMessage.error(res.msg)
          }
        })
      } else {
        console.log("登录失败")
      }
    })
  }
</script>

<style scoped>
  .login-container {
    height: 100vh;
    overflow: hidden;
    background-image: url("@/assets/welcome.jpg");
    background-size: 100% 100%;
  }
  .login-box {
    height: 100%;
    width: 50%;
    right: 0;
    position: absolute;
    display: flex;
    align-items: center;
    padding-left: 30px;
  }
</style>

在index.js中进行路由配置

代码语言:javascript
复制
{
      path: '/login',
      name: 'login',
      meta : { title : '登录系统'},
      component: () => import('../views/Login.vue'),
    },
后端处理
代码语言:javascript
复制
@PostMapping("/login")
public Result login(@RequestBody Employee employee) {
    Employee dbEmployee = employeeService.login(employee);
    return Result.success(dbEmployee);
}
代码语言:javascript
复制
public Employee login(Employee employee) {
        String username = employee.getUsername();
        Employee dbEmployee = employeeMapper.selectByUsername(username);
        if (dbEmployee == null) { //没查询到任何用户
            throw new CustomException("500", "账号不存在");
        }
        // 账号存在,判断密码
        String password = employee.getPassword();
        if (!dbEmployee.getPassword().equals(password)) { //用户输入的密码跟数据库账号的密码不匹配
            throw new CustomException("500", "账号或密码错误");
        }
        return dbEmployee;
    }

登录页面的设计图

注册

注册页面的确认密码怎么做表单校验?

Form 表单 | Element Plus

在表单项加入对应的prop

定义prop触发的函数和validatePass校验规则

代码语言:javascript
复制
const validatePass = (rule, value, callback) => {
  if (!value) {
    callback(new Error('请再次确认密码'))
  } else if (value !== data.form.password) {
    callback(new Error("两次输入的密码不一致"))
  } else {
    callback()
  }
}

const data = reactive({
  form:{},
  rules :{
    username: [
      { required: true, message: "请输入账号", trigger: "blur" }
    ],
    password: [
      { required: true, message: "请输入密码", trigger: "blur" }
    ],
    confirmPassword: [
      { validator: validatePass, trigger: "blur"}
    ]
  }
})
后端代码
代码语言:javascript
复制
@PostMapping("/register")
public Result register(@RequestBody Employee employee) {
    employeeService.register(employee);
    return Result.success();
}
代码语言:javascript
复制
public void add(Employee employee) {
        String username = employee.getUsername();
        Employee dbEmployee = employeeMapper.selectByUsername(username);
        if (dbEmployee != null) { // 注册的账号已存在,无法注册
            throw new CustomException("500", "账号已存在,请更换别的账号");
        }
        if (StrUtil.isBlank(employee.getPassword())) { // 密码没填
            employee.setPassword("123"); // 默认密码123
        }
        if (StrUtil.isBlank(employee.getName())) { // 名字没填
            employee.setName(employee.getUsername());
        }
        // 一定要设置角色
        employee.setRole("EMP");
        employeeMapper.add(employee);
    }
前端代码
代码语言:javascript
复制
<template>
  <div>
    <div class="login-container">
      <div class="login-box">
        <div style="padding: 50px 30px; background-color: white; border-radius: 5px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.5)">
          <el-form ref="formRef" :rules="data.rules" :model="data.form" style="width: 400px">
            <div style="margin-bottom: 30px; font-size: 25px; color: blue; font-weight: bold; text-align: center">欢迎登录后台管理系统</div>
            <el-form-item label="账号:" prop="username">
              <el-input size="large" v-model="data.form.username" placeholder="请输入账号"
                        prefix-icon="User"></el-input>
            </el-form-item>
            <el-form-item label="密码:" prop="password">
              <el-input size="large" v-model="data.form.password" placeholder="请输入密码" prefix-icon="Lock" show-password></el-input>
            </el-form-item>
            <el-form-item label="确认密码:" prop="confirmPassword">
              <el-input size="large" v-model="data.form.confirmPassword" placeholder="请确认密码" prefix-icon="Lock" show-password></el-input>
            </el-form-item>
            <div style="margin-bottom: 20px">
              <el-button size="large" type="primary" style="width: 100%"  @click="register">注册</el-button>
            </div>
            <div style="text-align: right">
              已有账号?请<a href="/login" style="color: #909399; text-decoration: none"> 登录</a>
            </div>
          </el-form>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { reactive,ref } from "vue";
import { User, Lock } from "@element-plus/icons-vue"
import request from "@/utils/request.js";
import {ElMessage} from "element-plus";

const validatePass = (rule, value, callback) => {
  if (!value) {
    callback(new Error('请再次确认密码'))
  } else if (value !== data.form.password) {
    callback(new Error("两次输入的密码不一致"))
  } else {
    callback()
  }
}

const data = reactive({
  form:{},
  rules :{
    username: [
      { required: true, message: "请输入账号", trigger: "blur" }
    ],
    password: [
      { required: true, message: "请输入密码", trigger: "blur" }
    ],
    confirmPassword: [
      { validator: validatePass, trigger: "blur"}
    ]
  }
})

const formRef = ref()

const register = () => {
  formRef.value.validate(valid => {
    if (valid) {
      request.post("/register", data.form).then(res => {
        if (res.code === '200') {
          // 存储后台返回的用户数据信息
          localStorage.setItem("user", JSON.stringify(res.data)) // 把json对象转换成json字符串存储
          console.log(res.data)
          ElMessage.success('注册成功')
          location.href='/login'
        } else {
          ElMessage.error(res.msg)
        }
      })
    } else {
      console.log("注册失败")
    }
  })
}


</script>

<style scoped>
.login-container {
  height: 100vh;
  overflow: hidden;
  background-image: url("@/assets/welcome.jpg");
  background-size: 100% 100%;
}
.login-box {
  height: 100%;
  width: 50%;
  right: 0;
  position: absolute;
  display: flex;
  align-items: center;
  padding-left: 30px;
}
</style>

引入hutool工具包

Hutool参考文档

代码语言:javascript
复制
<dependency>
  <groupId>cn.hutool</groupId>
  <artifactId>hutool-all</artifactId>
  <version>5.8.20</version>
</dependency>

方便进行字符串判空

疑问:margin与padding之间的区别?

  • margin-bottom

作用:设置元素外部底部的空白区域,即该元素与其他相邻元素之间的距离。 影响范围:

  1. 控制当前元素和后续元素之间的垂直间距。
  2. 不会影响元素内部内容的位置。

示例:

代码语言:javascript
复制
  <div style="margin-bottom: 20px">登录按钮</div>
  <p>注册链接</p>

上面代码中,“登录按钮”与“注册链接”之间会有 20px 的空隙。

  • padding

作用:设置元素内部的填充,即内容与元素边框之间的空间。 影响范围:

  1. 控制元素内部内容(如文字、子元素)与元素边界之间的距离。
  2. 不会影响其他兄弟元素的布局。

示例:

代码语言:javascript
复制
  <div style="padding: 50px 30px">
    <!-- 内容会离 div 边界有 50px 的上下间距和 30px 的左右间距 -->
  </div>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-12-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前后端基础数据修改
    • 如何做表单的校验?
    • 如何关闭后清空选项?(也就是打开一个新的、无污染的对话框)
  • 开发登录注册
    • 登录
      • 前端处理
      • 后端处理
      • 注册页面的确认密码怎么做表单校验?
      • 后端代码
      • 前端代码
  • 引入hutool工具包
  • 疑问:margin与padding之间的区别?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档