Springboot + Mybatis + Vue3 实现登陆界面 创建项目
开发环境热部署 代码修改自动重新部署
pom.xml:
1 2 3 4 5 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-devtools</artifactId > <optional > true</optional > </dependency >
application.properties:
1 2 spring.devtools.resstart.enabled =true spring.devtools.restart.addtionall-paths =src/main/java
MyBatis pom.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <dependency > <groupId > org.mybatis.spring.boot</groupId > <artifactId > mybatis-spring-boot-starter</artifactId > <version > 3.0.0</version > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 5.1.47</version > </dependency > <dependency > <groupId > com.alibaba</groupId > <artifactId > druid-spring-boot-starter</artifactId > <version > 1.1.20</version > </dependency >
application.properties:
1 2 3 4 5 6 7 8 spring.datasource.type =com.alibaba.druid.pool.DruidDataSource spring.datasource.driver =com.mysql.jdbc.Driver spring.datasource.url =jdbc:mysql://localhost:3306/db_name?useSSL=false spring.datasource.username =root spring.datasource.password =abc123 mybatis-plus.configuration.log-impl =org.apache.ibatis.logging.stdout.StdOutImpl server.port =8088
修改 Springboot 版本,3+ 版本与 MyBatis 不兼容:
1 2 3 4 <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-parent</artifactId > <version > 2.7.5</version > <relativePath />
实现登陆注册功能 后端 前置条件:安装 MySql
创建Entity
1 2 3 4 5 6 7 public class User { private int userid; private String username; private String password; }
创建Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 @RestController @CrossOrigin public class UserController { @Autowired private UserMapper userMapper; @GetMapping("/user") public String findAll () { return userMapper.findAll().toString(); } @PostMapping("/login") public User login (@RequestBody User user) { User user1 = userMapper.findByUsername(user.getUsername()); if (user1 != null ) { if (user1.getPassword().equals(user.getPassword())) { return user1; } } return null ; } @PostMapping("/register") public User register (@RequestBody User user) { User user1 = userMapper.findByUsername(user.getUsername()); if (user1 == null ) { userMapper.insert(user); return user; } return null ; } @PostMapping("/delete") public User delete (int userid) { User user = userMapper.findById(userid); if (user != null ) { userMapper.deleteById(userid); return user; } return null ; } }
创建Mapper
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public interface UserMapper { @Select("select * from t_user") public List<User> findAll () ; @Insert("insert into t_user (username, password) values (#{username}, #{password})") public void insert (User user) ; @Select("select * from t_user where username = #{username}") public User findByUsername (String username) ; @Select("select * from t_user where id = #{id}") public User findById (Integer id) ; @Delete("delete from t_user where id = #{id}") public void deleteById (Integer id) ; }
启动类中映射数据库
1 2 3 4 5 6 7 @SpringBootApplication @MapperScan("com.example.demo.mapper") public class DemoApplication { public static void main (String[] args) { SpringApplication.run(DemoApplication.class, args); } }
前端 前置条件:安装 nodejs
安装 Vue Cli
安装 Element UI
1 npm install element-plus --save
安装 Vue Router
1 npm install vue-router@4
安装 Axios
创建 Vue 项目
main.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import { createApp } from 'vue' import App from './App.vue' import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' import router from './router' const app = createApp (App )app.use (ElementPlus ) app.use (router) app.mount ('#app' )
index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 import { createRouter, createWebHistory } from 'vue-router' import LoginComp from '@/components/LoginComp.vue' import HelloWorld from "@/components/HelloWorld.vue" import RegisterComp from "@/components/RegisterComp.vue" import WelcomeView from "@/views/WelcomeView.vue" const routes = [ { path : '/' , component : WelcomeView , children : [ { path : '' , component : LoginComp }, { path : 'register' , component : RegisterComp } ] }, { path : '/helloworld' , component : HelloWorld }, ]; const router = createRouter ({ history : createWebHistory (), routes, }); export default router;
LoginComp.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 <template> <div style ="text-align: center;margin: 0 20px" > <div style ="margin-top: 150px" > <div style ="font-size: 25px;font-weight: bold" > demo</div > </div > <div style ="margin-top: 50px" > <el-form :model ="loginForm" > <el-form-item prop ="username" > <el-input v-model ="loginForm.username" type ="text" placeholder ="用户名/邮箱" > <template #prefix > <el-icon > <User /> </el-icon > </template > </el-input > </el-form-item > <el-form-item prop ="password" > <el-input v-model ="loginForm.password" type ="password" placeholder ="密码" > <template #prefix > <el-icon > <Lock /> </el-icon > </template > </el-input > </el-form-item > </el-form > </div > <div style ="margin-top: 40px" > <el-button @click ="login()" style ="width: 270px" type ="success" plain > 立即登录</el-button > </div > <el-divider > <span style ="color: grey;font-size: 13px" > 没有账号</span > </el-divider > <div > <el-button style ="width: 270px" @click ="router().push('/register')" type ="warning" plain > 注册账号</el-button > </div > </div > </template> <script > import axios from 'axios' import {User , Lock } from '@element-plus/icons-vue' import router from "@/router" ;export default { components : {User , Lock }, data ( ) { return { loginForm : { username : '' , password : '' , }, }; }, methods : { router ( ) { return router }, login ( ) { axios ({ method : 'post' , url : 'http://localhost:8088/login' , data : { username : this .loginForm .username , password : this .loginForm .password } }) .then (response => { if (response.data ) { console .log ('Login successful:' , response.data ); this .$router .push ('/helloworld' ); } else { console .error ('Login failed:' , 'Invalid credentials' ); } }) .catch (error => { console .error ('Login failed:' , error); }) } }, }; </script > <style > </style >
RegisterComp.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 <template> <div style ="text-align: center;margin: 0 20px" > <div style ="margin-top: 100px" > <div style ="font-size: 25px;font-weight: bold" > 注册新用户</div > </div > <div style ="margin-top: 50px" > <el-form :model ="signupForm" > <el-form-item prop ="username" > <el-input v-model ="signupForm.username" :maxlength ="8" type ="text" placeholder ="用户名" > <template #prefix > <el-icon > <User /> </el-icon > </template > </el-input > </el-form-item > <el-form-item prop ="password" > <el-input v-model ="signupForm.password" :maxlength ="16" type ="password" placeholder ="密码" > <template #prefix > <el-icon > <Lock /> </el-icon > </template > </el-input > </el-form-item > <el-form-item prop ="password_repeat" > <el-input v-model ="signupForm.password_repeat" :maxlength ="16" type ="password" placeholder ="重复密码" > <template #prefix > <el-icon > <Lock /> </el-icon > </template > </el-input > </el-form-item > </el-form > </div > <div style ="margin-top: 80px" > <el-button style ="width: 270px" type ="warning" @click ="register" plain > 立即注册</el-button > </div > <div style ="margin-top: 20px" > <span style ="font-size: 14px;line-height: 15px;color: grey" > 已有账号? </span > <el-link type ="primary" style ="translate: 0 -2px" @click ="router().push('/')" > 立即登录</el-link > </div > </div > </template> <script > import {EditPen , Lock , Message , User } from "@element-plus/icons-vue" ;import axios from "axios" ;import router from "@/router" ;export default { components : {EditPen , Lock , Message , User }, data ( ) { return { signupForm : { username : '' , password : '' , }, }; }, methods : { router ( ) { return router }, register ( ) { if (this .signupForm .password !== this .signupForm .password_repeat ) { this .$message({ message : '密码不一致' , type : "error" }); console .error ('Passwords do not match' ); return ; } axios ({ method : 'post' , url : 'http://localhost:8088/register' , data : { username : this .signupForm .username , password : this .signupForm .password , } }) .then (response => { if (response.data ) { console .log ('Signup successful:' , response.data ); this .$message({ message : '注册成功' , type : 'success' }); this .$router .push ('/' ); } else { console .error ('Login failed:' , 'Invalid credentials' ); } }) .catch (error => { console .error ('Login failed:' , error); }) } }, }; </script >
WelcomeView.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 <template> <div style ="width: 98vw;height: 98vh;overflow: hidden;display: flex;" > <div style ="flex: 1" > <el-image style ="width: 100%;height: 100%" fit ="cover" :src ="require('../assets/wallhaven.jpg')" /> </div > <div class ="welcome-title" > <div style ="font-size: 30px;font-weight: bold" > demo</div > </div > <div style ="width: 400px;background-color: white;z-index: 1" > <router-view v-slot ="{ Component }" > <transition name ="el-fade-in-linear" mode ="out-in" > <component :is ="Component" style ="height: 100%" /> </transition > </router-view > </div > </div > </template> <script > </script > <style scoped > .welcome-title { position : absolute; bottom : 30px ; left : 30px ; color : white; text-shadow : 0 0 10px black; } </style >
App.vue
1 2 3 4 5 6 7 8 9 10 11 12 <template> <router-view > </router-view > </template> <script > export default { name : 'App' , }; </script > <style > </style >
效果