这里是一次对vue3+springboot+mybatis+mysql的项目实现,简朴实现前后端分离的登录注册功能,重要工具:idea,navicat
目次
一、创建vue3项目并初始设置
创建vue3项目
2.修改项目布局
1)原始目次布局
2)修改后目次布局
编辑编写登录注册页面
1)LoginAndRegister.vue
2)Home.vue
3)router
4)Login.css
5)登录注册页面展示
二、创建springboot+mysql+mybatis项目并毗连数据库
三、编写登录注册后端功能
1.登录逻辑
2.注册逻辑
3.后端代码部门
四、运行项目
一、创建vue3项目并初始设置
1.创建vue3项目
创建项目可参考我的一篇文章:
用IDEA创建自界说vue3项目_idea vue3-CSDN博客
创建后的初始目次布局:
2.修改项目布局
起首必要修改原始目次布局
1)原始目次布局
assets放图片
components中放组件,通常可复用
router是路由,全部重要页面的文件路径在此中设置
store一样平常是用于vuex状态管理,如存储token等
views中是重要页面
App.vue是Vue应用的根组件。
main.js是应用的入口文件,通常用于引入vue和vue router等依靠。
2)修改后目次布局
要实现登录注册功能,修改后的目次布局:
3.编写登录注册页面
1)LoginAndRegister.vue
在components文件夹下创建LoginAndRegister.vue,用于实现登录注册页面及功能,这里我的登录和注册只创建一个.vue文件,在此中通过v-if来决定登录块和注册快的元素部门是否被渲染,从而影响它们的表现。
初始时设置
- v-if="loginShow"为true, v-if="registerShow"为false
复制代码 当点击按钮举行切换时,将true和false切换。
注册乐成后切换回登录部门。
这里为了方便以及用户风俗,固然用户的属性有id,username,password,phone,gender五个,但注册时只填写用户名和暗码,且只是简朴实现功能,未对暗码举行加密处理处罚不敷安全,之后大概会再更新文章,写写更安全的登录注册方式,以及登录后怎样完满个人信息。
LoginAndRegister.vue:
- <template>
- <div class="container">
- <div class="login-box" v-if="loginShow">
- <!-- 菱形群-->
- <div class="decoration1 decoration"></div>
- <div class="decoration2 decoration"></div>
- <div class="decoration3 decoration"></div>
- <div class="decoration4 decoration"></div>
- <div class="decoration5 decoration"></div>
- <div class="decoration decoration4 decoration6"></div>
- <div class="decoration decoration7 decoration2"></div>
- <div class="decoration decoration8 decoration3"></div>
- <div class="login-title">
- <h1>Login</h1>
- </div>
- <div class="login-part">
- <input class="login-input" v-model="username" placeholder="Username" />
- <input class="login-input" type="password" v-model="password" placeholder="Password" />
- <button class="login-button" @click="login">Login</button>
- <div>
- 还未注册?点击<a class="change-link" @click="changeToRegister">这里</a>注册
- </div>
- </div>
- </div>
- <div class="login-box" v-if="registerShow">
- <!-- 菱形群-->
- <div class="decoration1 decoration"></div>
- <div class="decoration2 decoration"></div>
- <div class="decoration3 decoration"></div>
- <div class="decoration4 decoration"></div>
- <div class="decoration5 decoration"></div>
- <div class="decoration decoration4 decoration6"></div>
- <div class="decoration decoration7 decoration2"></div>
- <div class="decoration decoration8 decoration3"></div>
- <div class="login-title">
- <h1>Register</h1>
- </div>
- <div class="login-part">
- <input class="login-input" v-model="username" placeholder="Username" />
- <input class="login-input" type="password" v-model="password" placeholder="Password" />
- <button class="login-button" @click="register">Register</button>
- <span class="change-link" @click="changeToLogin">返回登录</span>
- </div>
- </div>
- <!-- <div class="decoration decoration1"></div>-->
- <!-- <div class="decoration decoration2"></div>-->
- <!-- <div class="decoration decoration3"></div>-->
- <!-- <div class="decoration decoration4"></div>-->
- </div>
- </template>
- <script>
- import { ref } from 'vue'
- import { useRouter } from 'vue-router' // 导入 useRouter
- import '../style/Login.css' // 导入css
- export default {
- name: 'LoginVue',
- setup () {
- const username = ref('')
- const password = ref('')
- const phone = ref('')
- const loginShow = ref(true)
- const registerShow = ref(false)
- const router = useRouter()
- const changeToRegister = async () => {
- loginShow.value = false
- registerShow.value = true
- }
- const changeToLogin = async () => {
- loginShow.value = true
- registerShow.value = false
- }
- const login = async () => {
- console.log('Login with:', username.value, password.value)
- try {
- const formData = new FormData()
- formData.append('username', username.value)
- formData.append('password', password.value)
- const response = await fetch('http://localhost:8081/api/user/login', {
- method: 'POST',
- body: formData
- })
- const data = await response.json()
- if (response.ok) {
- console.log('Link success', data)
- if (data.code === 200) {
- // 登录成功
- alert('登录成功!')
- await router.push('/home')
- } else {
- alert(data.msg)
- }
- } else {
- console.error('Link failed', data)
- }
- } catch (error) {
- console.error('Error login', error)
- }
- }
- const register = async () => {
- console.log('Register with:', username.value, password.value)
- try {
- const formData = new FormData()
- formData.append('username', username.value)
- formData.append('password', password.value)
- const response = await fetch('http://localhost:8081/api/user/register', {
- method: 'POST',
- body: formData
- })
- const data = await response.json()
- if (response.ok) {
- if (data.code === 200) {
- console.log('Register success', data)
- alert('注册成功!')
- await changeToLogin()
- } else {
- console.log('Register failed', data)
- alert(data.msg)
- }
- } else {
- console.error('Register failed', data)
- }
- } catch (error) {
- console.error('Error during register', error)
- }
- }
- return { username, password, phone, login, loginShow, registerShow, changeToRegister, register, changeToLogin }
- }
- }
- </script>
- <style>
- </style>
复制代码 2)Home.vue
Home.vue为登录乐成后跳转到的主页面。
Home.vue:
- <template>
- 首页<br><br>
- <button class="login-button" @click="signOut">退出登录</button>
- </template>
- <script>
- import { useRouter } from 'vue-router'
- export default {
- name: 'HomeVue',
- setup () {
- const router = useRouter()
- const signOut = async () => {
- await router.push('/')
- }
- return { signOut }
- }
- }
- </script>
- <style scoped>
- </style>
复制代码 3)router
页面路由设置,路径为/时重定向到登录页,/login为登录页,/home为首页。
index.js:
- import { createRouter, createWebHistory } from 'vue-router'
- import Login from '../components/LoginAndRegister.vue'
- import Home from '../views/Home.vue'
- const routes = [
- {
- path: '/',
- redirect: '/login'
- },
- {
- path: '/login',
- name: 'Login',
- component: Login
- },
- {
- path: '/home',
- name: 'Home',
- component: Home
- }
- ]
- const router = createRouter({
- history: createWebHistory(process.env.BASE_URL),
- routes
- })
- export default router
复制代码 4)Login.css
对登录注册页面的css计划。
Login.css:
- *{
- margin: 0;
- padding: 0;
- }
- .container{
- height: 100vh;
- display: flex;
- justify-content: center;
- align-items: center;
- overflow: hidden;
- position: relative;
- }
- .login-box{
- background-color: white;
- padding: 40px 100px;
- border-radius: 8px;
- box-shadow: 0 0 5px 1px gainsboro;
- position: relative;
- }
- .login-part{
- display: flex;
- flex-direction: column;
- justify-content: center;
- margin-top: 20px;
- gap: 20px;
- }
- .login-input{
- width: 250px;
- height: 30px;
- border-radius: 8px;
- }
- .login-button{
- height: 40px;
- border-radius: 8px;
- background-color: #2c3e50;
- color: white;
- transition: 0.5s;
- }
- .login-button:hover{
- background-color: darkcyan;
- font-size: 15px;
- transition: 0.5s;
- }
- .login-button:active{
- background-color: darkslateblue;
- }
- .change-link{
- color: #00BFFF;
- text-decoration: underline;
- }
- .change-link:hover{
- color: cornflowerblue;
- }
- .decoration {
- position: absolute;
- width: 200px;
- height: 200px;
- background: linear-gradient(to left, #FDF5E6, #96CDCD );
- clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
- z-index: 1;
- }
- .decoration1 {
- top: 150px;
- left: -210px;
- }
- .decoration2 {
- top: 20px;
- right: -20px;
- width: 100px; /* 第二个菱形的大小 */
- height: 100px;
- background: linear-gradient(to right, #FFF5EE, #E6E6FA);
- }
- .decoration3 {
- top: 50px;
- right: -180px;
- width: 200px; /* 第三个菱形的大小 */
- height: 200px;
- background: linear-gradient(to right, #7FFFD4, cadetblue);
- }
- .decoration4 {
- top: 200px;
- right: -200px;
- width: 500px; /* 第三个菱形的大小 */
- height: 500px;
- z-index: -1;
- clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
- background: linear-gradient(to right, #FFFACD, #00BFFF);
- }
- .decoration5 {
- top: -100px;
- right: 200px;
- width: 400px; /* 第三个菱形的大小 */
- height: 400px;
- z-index: -1;
- clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
- background: linear-gradient(to right, #AFEEEE, #00BFFF);
- }
- .decoration6 {
- top: 10px;
- right: -680px;
- }
- .decoration7 {
- top: -170px;
- right: -500px;
- }
- .decoration8 {
- top: -140px;
- right: -655px;
- }
复制代码 5)登录注册页面展示
此中的菱形块是恣意排布的,一开始是如许的:
厥后多加了几个菱形块,改变他们的位置和颜色,终极效果如下:
二、创建springboot+mysql+mybatis项目并毗连数据库
用springboot,mysql,mybatis简朴建一个后端项目并毗连数据库,参考:
idea,spring boot+MySQL+MyBatis项目创建并在网页中表现数据库表中内容_idea将数据库表现到网页-CSDN博客
对文章增补:
以为创建实体类每次都要写set和get方法比力贫苦,可以在pom.xml中添加如下依靠:
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </dependency>
复制代码 然后在entity的实体类中用@Data注解,就可省略写set和get方法:
过程差不多,不外此次创建我的数据不太一样,重要是user表属性和数据发生变革(差别不大,换汤不换药):
碰到标题:maven不绝下载依靠,好久没反应
但是在创建项目途中还是出了点儿标题的,这次使用的是新电脑创建后端项目,第一次建,效果maven启动后不绝在下载各种依靠和插件,而且好久没有反应:
办理方式:
清空缓存重启idea,但效果不大。
厥后发现大概是由于Maven默认使用国外的中央堆栈,且我用的是idea中的maven插件,以是下载速率会很慢。
以是还是在本地下载了maven,参考教程:
maven的下载与安装教程(超具体)_maven安装-CSDN博客
按教程下载,在maven安装路径->conf->settings.xml中修改镜像的url,不外我没有设置情况变量,直接在idea中file->settings->Build,Execution,Deployment->Build Tools->Maven中,将Maven home path改为本地路径:
改完之后下载速率果然快了很多。
终极后端项目标目次布局如下:
三、编写登录注册后端功能
1.登录逻辑
获取前端通报的填写信息,包罗用户名和暗码,在数据库中根据用户名和暗码举行查询,如果找到用户,阐明用户存在且用户名与暗码对应,登录乐成,否则失败。
2.注册逻辑
获取前端通报的填写信息,包罗用户名和暗码,判断输入信息不为空后,在数据库中先根据用户名查找用户,如果找到了,即用户名已存在,注册失败,返回失败信息,如果未找到用户,则可以注册,向数据库中插入该条记载,而且注册乐成后展示登录块,埋伏注册块。
3.后端代码部门
此中resources->mapper->UserMapper.xml:
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
- "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
- <mapper namespace="com.example.demo.mapper.UserMapper" >
- <resultMap id="result" type="com.example.demo.entity.User">
- <result property="id" column="id" />
- <result property="username" column="username" />
- <result property="password" column="password" />
- <result property="phone" column="phone" />
- <result property="gender" column="gender"/>
- </resultMap>
- <!-- 通过用户名和密码查找对应用户,用于登录-->
- <select id="findUserByNameAndPwd" resultMap="result" parameterType="User">
- select * from user
- where username = #{username}
- and password = #{password}
- </select>
- <!-- 通过用户名查找对应用户,用于注册检验用户名是否已存在-->
- <select id="findUserByName" resultMap="result" parameterType="User">
- select * from user
- where username = #{username}
- </select>
- <!-- 添加用户-->
- <insert id="addUser" parameterType="User">
- insert into user (username, password)
- values ( #{username}, #{password} )
- </insert>
- </mapper>
复制代码 java->com.example.demo->mapper->UserMapper.java:
- package com.example.demo.mapper;
- import com.example.demo.entity.User;
- import org.apache.ibatis.annotations.Mapper;
- @Mapper
- public interface UserMapper {
- // 通过用户名和密码查找对应用户
- public User findUserByNameAndPwd(User user);
- // 通过用户名查找用户
- public User findUserByName(User user);
- // 添加用户
- public void addUser(User user);
- }
复制代码 java->com.example.demo->service->UserService.java:
- package com.example.demo.service;
- import com.example.demo.entity.User;
- public interface UserService {
- // 通过用户名和密码查找对应id
- public User findUserByNameAndPwd(User user);
- // 通过用户名查找用户
- public User findUserByName(User user);
- // 添加用户
- public void addUser(User user);
- }
复制代码 java->com.example.demo->service->UserServiceImpl.java:
- package com.example.demo.service;
- import com.example.demo.entity.User;
- import com.example.demo.mapper.UserMapper;
- import jakarta.annotation.Resource;
- import org.springframework.stereotype.Service;
- @Service
- public class UserServiceImpl implements UserService {
- @Resource
- private UserMapper userMapper;
- // 通过用户名和密码查找对应id
- @Resource
- public User findUserByNameAndPwd(User user){
- return userMapper.findUserByNameAndPwd(user);
- }
- // 通过用户名查找用户
- @Resource
- public User findUserByName(User user){
- return userMapper.findUserByName(user);
- }
- // 添加用户
- @Resource
- public void addUser(User user){
- userMapper.addUser(user);
- }
- }
复制代码 java->com.example.demo->controller->UserController.java:
- package com.example.demo.controller;
- import com.example.demo.entity.User;
- import com.example.demo.result.Result;
- import com.example.demo.service.UserService;
- import jakarta.annotation.Resource;
- import org.springframework.web.bind.annotation.*;
- @RestController
- @RequestMapping("/api/user")
- public class UserController {
- @Resource
- UserService userService;
- // 登录
- @CrossOrigin
- @PostMapping(value = "/login")
- public Result login(@ModelAttribute("user") User user){
- String username=user.getUsername();
- String password=user.getPassword();
- System.out.println("Login received username: " + username);
- System.out.println("Login received password: " + password);
- User userCheck = new User();
- userCheck.setUsername(username);
- userCheck.setPassword(password);
- System.out.println(userCheck.getUsername() + " " + userCheck.getPassword());
- try{
- User findUser = userService.findUserByNameAndPwd(userCheck);
- if(findUser != null){
- return Result.success(findUser);
- }else {
- return Result.failure(401,"用户名或密码错误");
- }
- }catch (Exception e){
- return Result.failure(500,"服务器异常");
- }
- }
- // 注册
- @CrossOrigin
- @PostMapping(value = "/register")
- public Result register(@ModelAttribute("user") User user){
- // String username = "222";
- // String password = "222";
- User userCheck = new User();
- userCheck.setUsername(user.getUsername());
- userCheck.setPassword(user.getPassword());
- if(userCheck.getUsername() == null || userCheck.getUsername().isEmpty() || userCheck.getPassword() == null || userCheck.getPassword().isEmpty()){
- System.out.println("用户名或密码不可为空");
- return Result.failure(201,"用户名和密码不可为空");
- }else {
- System.out.println("Register received username: " + userCheck.getUsername());
- System.out.println("Register received password: " + userCheck.getPassword());
- try{
- // 先在数据库中查找是否已有用户名相同的用户
- User findUser = userService.findUserByName(userCheck);
- if(findUser != null){
- // 用户名已存在
- return Result.failure(202,"用户名已存在!");
- }
- else {
- // 新用户,数据库添加记录
- userService.addUser(userCheck);
- return Result.success(userCheck);
- }
- }catch (Exception e) {
- return Result.failure(500, "服务器异常");
- // }
- }
- }
- }
- }
复制代码 四、运行项目
前后端分别运行启动,这里我把后端的端口在application.properties中改为了8081,前端为默认的8080,以是在前后端项目都乐成运行后,在欣赏器输入http://localhost:8080即可,在开发者工具的network中查察,乐成毗连到后端,而且当登录注册举行测试输入时能乐成返回差别的提示信息并弹窗提示:
登录乐成之后:
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金 |