手把手教你制作登录、注册界面 SpringBoot+Vue.js(cookie的灵活运用,验证码功能)
一、用户登录界面
实现思路:用户在界面输入用户名和密码传入变量。用post方法传输到后端,后端接收整个实体对象。将用户名提取出。在dao层方法中通过select注解查询,返回数据库对应的数据对象。如果返回为空则return false。不为空则通过比对数据库返回的密码和用户输入的密码,如果二者匹配则return true,否则return false。在前端axios框架中,通过if语句判断,如果return true则提示登录成功信息,跳转到首页。如果return false则提示登录失败请重试。
效果:
![]()

![]()

![]()
改进思路:
用cookie记住用户的登录状态。1. 在首页上方显示“欢迎xxx登录!!”字样,xxx必须根据用户名动态变化。2. 已登录状态在右上角显示“个人中心”,个人中心下拉显示“退出登录”,未登录则显示“登录”,无个人中心。3. 实现退出登录的功能。4.设置一个具有权限的页面,如果未登录页面上方弹窗显示“权限不足,请登录”,如果已登录则可以正常浏览页面内容。5. 对登录的用户名和密码进行加密,接收端进行解密匹配。
1.1 初始版本
第1步:dao层编写如下代码:
@Select("select * from tb_user where username=#{username}" )
public User login(String username);
第2步: controller层编写如下代码:
@RestController
@RequestMapping("/api/")
public class DataController {@PostMapping("login")public boolean loginmodule(@RequestBody User user){System.out.println(user.getUsername());System.out.println(user.getPassword());User u = bookDao.login(user.getUsername());if(u==null) return false;System.out.println(u.getPassword());if(user.getPassword().equals(u.getPassword())) return true;else return false;}
}
第3步:编写请求代码:
methods: {login() {axios.post("/api/login",this.form).then((response)=>{if(response.data==true) {confirm('登录成功!');window.location.href="home.html";}else alert('用户名或密码错误,请重试!');})},
}
第4步: 编写登录界面,定义变量:
登录界面:
<!--登录界面-->
<h1 style="margin-left:125px;color: #333333">登录</h1>
<el-form ref="form" :model="form" label-width="80px" style="margin-top: 30px"><el-form-item label="用户名"><el-input v-model="form.username" style="width: 200px;"></el-input></el-form-item><el-form-item label="密码"><el-input v-model="form.password" style="width: 200px;"></el-input></el-form-item><div style="margin-left: 200px;margin-bottom: 15px"><el-link type="primary" @click="register" >点击注册</el-link></div><el-form-item><el-button type="primary" @click="login">登录</el-button><el-button>取消</el-button></el-form-item>
</el-form>
定义变量:
data() { return {form: {username: '',password: ''
} } }
1.2 完善版本
技术难点1:cookie如何定义
document.cookie = `loginStatus=true,username=${this.form.username}`;这句话定义了2个cookie,注意不同的cookie间最好以逗号分割。等号左边两边分别是键和值,以键值对的形式目的是方便切割。
methods: {login() {axios.post("/api/login",this.form).then((response)=>{if(response.data==true) {confirm('登录成功!');document.cookie = `loginStatus=true,username=${this.form.username}`;window.location.href="home.html";}else alert('用户名或密码错误,请重试!');})
},
— — — — — — 知识加油站 — — — — — —
1. ${}是 JavaScript 中的模板字符串语法。它允许在字符串中插入动态的表达式或变量。最终会被解析为具体的值。
2. 在 JavaScript 中document对象提供了一个cookie属性,用于访问和操作浏览器中的 cookie。
3. Cookie 是存储在用户计算机上的小型文本文件,用于在浏览器和服务器之间存储和传递数据。它可以用于在用户的不同请求之间存储会话信息、用户偏好设置、购物车数据等。
— — — — — — — — — — — — — — — —
技术难点2:如何提取cookie中的目标数据,进行实时显示
上面定义完cookie之后可以直接通过document.cookie直接取得cookie,然而此时的cookie还是以字符串的形式存在,所以需要进行适当的切分:
function getCookie(username){const cookies = document.cookie.split(",")for(let i=0;i<cookies.length;i++){const cookie = cookies[i].split('=');if(cookie[0]==username) return cookie[1];}return "";
}
cookies就是loginStatus=true和username=${this.form.username}。cookie就是loginStatus,true,username,${this.form.username}。
通过匹配cookie[0]是否是username键,可以返回username的值,供前端实时显示欢迎xxx。
技术难点3:如何根据登录与否,显示不同的页面样式
document.addEventListener("DOMContentLoaded", function() {// 在首页上方显示欢迎信息和登录状态const loginStatus = getCookie("loginStatus"); //获取loginStatus的值赋值给loginStatus,是true或falseconst welcomeMessage = document.getElementById("welcome-message");const loginStatusText = document.getElementById("login-status");if (loginStatus === "true") {// 已登录状态const username = getCookie("username"); // 假设用户名保存在名为"username"的cookie中console.info(username);welcomeMessage.textContent = "欢迎 " + username + " 登录!!";} else {// 未登录状态welcomeMessage.textContent = "";loginStatusText.textContent = "登录";}
});
技术难点2和难点3的代码需要同导航栏的代码进行配套使用,才能保证各个页面的一致性,因此可以把上述两段代码封装到一个cookie.js中,然后需要引用的时候就在前端加上如下代码即可:
<script src="cookie.js"></script>
— — — — — — 知识加油站 — — — — — —
1. <script src="navigation.js"></script>这段代码用于在页面中引入navigation.js文件,该文件包含了导航栏和登录界面的代码。
2. <div id="navigation"></div>这段代码创建了一个空的<div>元素,并为其设置了一个唯一的 id 属性值为 "navigation"。这个 div 元素将被用于展示导航栏的代码。
3. <script>document.getElementById("navigation").innerHTML = navigationCode;</script>这段代码使用 JavaScript 获取到 id 为navigation的 div 元素,并将导航栏的代码navigationCode插入到这个 div 元素中。这样就将导航栏的代码动态地展示在页面上。
4.<div>标签本身不具备任何特定的语义或功能,它只是一个用于容纳其他 HTML 元素的容器。
— — — — — — — — — — — — — — — —
技术难点4:如何封装前端重复性的代码
前端的每个页面都具有导航栏,每个导航栏的代码如下这么长,如果每个页面都填写,显得及其臃肿。
于是我们选择将代码封装到一个navigation.js的文件中,
const navigationCode = `
<el-menu:default-active="activeIndex2"class="el-menu-demo"mode="horizontal"@select="handleSelect"background-color="#545c64"text-color="#fff"active-text-color="#ffd04b"><el-menu-item><a href="ADSS.html" style="font-size: large;text-decoration: none;">数据查询</a></el-menu-item><el-menu-item><a href="home.html" style="font-size: large;text-decoration: none;">首页</a></el-menu-item><el-menu-item><a href="login.html" style="font-size: large;text-decoration: none;"><h id="login-status"></h></a></el-menu-item><el-submenu index="2" style=" position: absolute;right: 135px;" ><template slot="title">个人中心</template><el-menu-item @click="clear" >退出登录</el-menu-item></el-submenu><h5 id="welcome-message" style="color: #edf2fc;display: flex;justify-content: flex-end;"></h5></el-menu>`
见上面知识加油站:
<!--导航栏--><script src="navigation.js"></script><div id="navigation"></div><script>document.getElementById("navigation").innerHTML = navigationCode;</script>
二、用户注册界面
实现思路:用户输入用户名和密码,利用post方式传回后端,后端根据用户名比对数据是否已在数据库内(select),如果已在则直接提示登录跳转登录界面,如果不在则将数据插入数据库,然后提示注册成功,跳转登录界面。
实现效果:

![]()

![]()
![]()
改进思路:1. 增加验证码机制。2. 可以在旁边实时显示是否已注册。
第1步:dao层编写如下代码:
@Insert("Insert into tb_user(username,password) "+"values(#{username},#{password})")
public void register(User user);
@Select("select * from tb_user where username=#{username}" )
public User login(String username);
第2步:controller层编写如下代码,判断逻辑:通过用户输入的username,查看数据库中是否有相应的实体对象,如果有说明已注册,如果没有则将数据插入数据库。
@RestController
@RequestMapping("/api/")
public class DataController {@PostMapping("register")public boolean registermodule(@RequestBody User user){User compare = bookDao.login(user.getUsername()); //根据用户输入的用户名返回数据库中对应实体对象if(compare!=null) return false;bookDao.register(user);return true;}
}
第3步:编写注册界面,定义变量:
注册界面如下:
<!--注册界面-->
<h1 style="margin-left:100px;color: #333333">注册账号</h1>
<el-form ref="form" :model="form" label-width="80px" style="margin-top: 30px"><el-form-item label="用户名"><el-input v-model="form.username" style="width: 200px;"></el-input></el-form-item><el-form-item label="密码"><el-input v-model="form.password" style="width: 200px;"></el-input></el-form-item><el-form-item><el-button type="primary" @click="onSubmit">注册</el-button><el-button href="register.html">取消</el-button></el-form-item>
</el-form>
接收数据的变量如下:
data() {return {form: {username: '',password: ''},
第4步:编写请求代码:
onSubmit() {axios.post("/api/register",this.form).then((response)=>{if(response.data==false) alert("注册失败,用户名已存在!");else {confirm("注册成功,即将跳转登录界面")window.location.href="login.html";}})
}
相关文章:
手把手教你制作登录、注册界面 SpringBoot+Vue.js(cookie的灵活运用,验证码功能)
一、用户登录界面 实现思路:用户在界面输入用户名和密码传入变量。用post方法传输到后端,后端接收整个实体对象。将用户名提取出。在dao层方法中通过select注解查询,返回数据库对应的数据对象。如果返回为空则return false。不为空则通过比对…...
C++ Qt零基础入门进阶与企业级项目实战教程与学习方法分享
Qt是一个卓越的客户端跨平台开发框架,可以在Windows、Linux、macOS进行客户端开发,无缝切换,一统三端;当然除了桌面端,在移动端的早期,Qt也展现了其多才多艺,在Android和ios也可以使用Qt编写app…...
TypeScript学习记录
一、TS开发环境的搭建 1、下载并安装node.js 2、使用npm全局安装typeScript 进入命令行输入:npm i -g typescript 3、创建一个ts文件 4、使用tsc对ts文件进行编译 进入命令行进入ts文件所在目录执行命令:tsc 文件名.ts 二、TS基本变量 1、类型声…...
vue内置组件Transition的详解
1. Transition定义 Vue 提供了两个内置组件,可以帮助你制作基于状态变化的过渡和动画: <Transition>会在一个元素或组件进入和离开 DOM 时应用动画。 <TransitionGroup> 会在一个 v-for 列表中的元素或组件被插入,移动࿰…...
中秋节听夜曲,Android OpenGL 呈现周董专属的玉兔主题音乐播放器
概述 前几天发现QQ音乐有个好玩的功能,为用户提供了多种 播放器主题,其中 原神 的主题让我眼前一亮: 当然,诸如 换肤、主题 类的功能已经屡见不鲜,但这类沉浸式播放器的听歌体验确实不错。 见猎心喜,正好…...
008_第一代软件系统架构
第一代软件系统架构 文章目录 第一代软件系统架构项目介绍软件架构和软件构架系统框架硬件组成运行系统基础库软件层 系统架构 关键字: Qt、 Qml、 关键字3、 关键字4、 关键字5 项目介绍 欢迎来到我们的 QML & C 项目!这个项目结合了 QML&…...
oracle客户端的安装(SQL Developer)
参考资料 软件首页:https://www.oracle.com/database/sqldeveloper/ 官方文档:https://docs.oracle.com/en/database/oracle/sql-developer/ 下载地址:https://www.oracle.com/database/sqldeveloper/technologies/download/ 安装指南&#…...
Mysql索引优化1
关闭查询缓存 set global query_cache_size 0; set global query_cache_type 0; force index(索引)where 条件 强制走索引 一般不推荐,因为mysql结构中会通过cost计算出最优sql路线 索引下推 5.6之前 会先从辅助索引表也就是二级索引…...
Spring常考知识点(IOC、事务、容器等)
作者:逍遥Sean 简介:一个主修Java的Web网站\游戏服务器后端开发者 主页:https://blog.csdn.net/Ureliable 觉得博主文章不错的话,可以三连支持一下~ 如有需要我的支持,请私信或评论留言! Spring需要理解的问…...
Leetcode 2867. Count Valid Paths in a Tree
Leetcode 2867. Count Valid Paths in a Tree 1. 解题思路2. 代码实现 题目链接:2867. Count Valid Paths in a Tree 1. 解题思路 这一题思路上的话由于要求路径上有且仅有一个质数点,因此,一个直接的思路就是考察所有质数的点作为中心点时…...
Jtti:Ubuntu下如何创建XFS文件系统的LVM
在 Ubuntu 下创建一个 XFS 文件系统的 LVM(Logical Volume Manager)分区需要一系列步骤。以下是详细的步骤: 1. 创建物理卷 (PV) 首先,将要用于 LVM 的硬盘分区(物理卷)初始化为物理卷。假设你有一个硬盘…...
做销售管理分析需要看哪些关键指标?
做销售管理分析需要看哪些关键指标? 销售管理分析时抓取关键指标,有着能够【分析和判断销售趋势、为销售决策提供数据支持、优化销售流程和客户管理】等的好处 在了解了分析关键指标的目的之后,我们就可以根据企业的需求来确定关键指标&…...
【Python】自动完成手写字体图片贴入以及盖章工具
简介 该工具完成了如下功能: 1.将文字转换为手写体填入到模板文件中 2.自动将文字转换为盖章格式填入到模板文件中 3.字体格式可以替换 4.有配置文件进行扩展功能 功能模块 1.界面模块 import sys from PyQt5.QtWidgets import QApplication, QMessageBox, QWid…...
基于Xml方式Bean的配置-初始化方法和销毁方法
SpringBean的配置详解 Bean的初始化和销毁方法配置 Bean在被实例化后,可以执行指定的初始化方法完成一些初始化的操作,Bean在销毁之前也可以执行指定的销毁方法完成一些操作,初始化方法名称和销毁方法名称通过 <bean id"userService…...
实时更新进度条:JavaScript中的定时器和异步编程技巧
前言 在Web开发中,有许多场景需要实时地更新页面上的进度,例如上传文件、数据处理等。本文将介绍如何利用JavaScript中的定时器和异步编程技巧来实现实时更新进度,并探讨一些其他解决方案。 处理进度实时更新: 利用异步编程实现实…...
【简单图论】CF898 div4 H
Problem - H - Codeforces 题意: 思路: 手玩一下样例就能发现简单结论: v 离它所在的树枝的根的距离 < m 离这个根的距离时是 YES 否则就是NO 实现就很简单,先去树上找环,然后找出这个根,分别给a 和…...
【大虾送书第十一期】适合新手自学的网络安全基础技能“蓝宝书”:《CTF那些事儿》
目录 🥮写在前面 🥮内容简介 🥮读者对象 🥮专家推荐 🥮目录 🥮文末福利 🦐博客主页:大虾好吃吗的博客 🦐专栏地址:免费送书活动专栏地址 写在前面 CTF比赛是快…...
IDEA安装离线插件后重启无法打开
解决方法 1.找到插件安装目录删除插件 插件的位置一般在C:\Users\19058\AppData\Roaming\JetBrains\IntelliJIdea2021.1\plugins 高亮部分是自己电脑的用户位置,把报错前的刚才最新安装的插件删除,再尝试打开idea即可解决该问题 2.补充说明 AppData是个隐…...
论软件的可靠性设计
摘要 2021年6月,我所在的公司中标某集团保险大数据平台一体化研发项目,该项目总投资2000万人民币,项目周期为2年,通过该项目,搭建该集团保险大数据平台,一方面将全国所有保险业务全部入库并保存࿰…...
AG35学习笔记(一):debug串口抓取模组log、debug串口测试AT指令、echo命令通过串口发送16进制数据
目录 一、概述二、抓取模组log2.1 硬件接口2.2 用户登录2.3 相关指令 三、测试AT指令3.1 查看端口3.2 进入模式 四、串口发16进制echo使用 一、概述 二、抓取模组log 在之前记录了通过USB,使用移远工具Qwinlog来抓取log(3.3 抓取模组log)。…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...
es6+和css3新增的特性有哪些
一:ECMAScript 新特性(ES6) ES6 (2015) - 革命性更新 1,记住的方法,从一个方法里面用到了哪些技术 1,let /const块级作用域声明2,**默认参数**:函数参数可以设置默认值。3&#x…...
数据库正常,但后端收不到数据原因及解决
从代码和日志来看,后端SQL查询确实返回了数据,但最终user对象却为null。这表明查询结果没有正确映射到User对象上。 在前后端分离,并且ai辅助开发的时候,很容易出现前后端变量名不一致情况,还不报错,只是单…...
