Teknologian jakaminen

vue3 springboot mybatis mysql projekti harjoitus - yksinkertaisten kirjautumis- ja rekisteröintitoimintojen toteutus

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Tässä on projektitoteutus vue3+springboot+mybatis+mysql, joka yksinkertaisesti toteuttaa sisäänkirjautumis- ja rekisteröintitoiminnot front-end ja back-end erottamiseen Tärkeimmät työkalut ovat: idea, navicat

Sisällysluettelo

1. Luo vue3-projekti ja alkukokoonpano

Luo vue3-projekti

2. Muokkaa projektin rakennetta

1) Alkuperäinen hakemistorakenne

2) Muokattu hakemistorakenne

Muokkaa ja kirjoita sisäänkirjautumissivua

1) LoginAndRegister.vue

2) Home.vue

3) reititin

4) Kirjaudu.css

5) Kirjautumisrekisteröintisivun näyttö

2. Luo springboot+mysql+mybatis-projekti ja muodosta yhteys tietokantaan

3. Kirjoita sisäänkirjautumisen ja rekisteröinnin taustatoiminnot

1. Kirjautumislogiikka

2. Rekisteröintilogiikka

3. Taustakoodin osa

4. Suorita projekti


1. Luo vue3-projekti ja alkukokoonpano

1. Luo vue3-projekti

Voit luoda projektin tutustumalla yhteen artikkeleistani:

Luo mukautettu vue3-projekti IDEA_idea vue3-CSDN-blogin avulla

Alkuperäinen hakemistorakenne luomisen jälkeen:

2. Muokkaa projektin rakennetta

Ensin sinun on muutettava alkuperäistä hakemistorakennetta

1) Alkuperäinen hakemistorakenne

omaisuuttalaita kuvia

komponentitVälikomponentit, yleensä uudelleenkäytettäviä

reititinon reitti, jolla kaikkien pääsivujen tiedostopolut on määritetty

tallentaaYleensä käytetään vuex-tilan hallintaan, kuten tokenien tallentamiseen jne.

näkymätKeskus on pääsivu

App.vueSe on Vue-sovelluksen juurikomponentti.

main.jsSe on sovelluksen syöttötiedosto, jota käytetään yleensä tuomaan käyttöön riippuvuuksia, kuten vue ja vue-reititin.

2) Muokattu hakemistorakenne

Kirjautumis- ja rekisteröintitoiminnon toteuttamiseksi muutettu hakemistorakenne on:


3. Kirjoita sisäänkirjautumissivu

1) LoginAndRegister.vue

Luo LoginAndRegister.vue komponenttien kansioon toteuttaaksesi sisäänkirjautumis- ja rekisteröintisivun ja toiminnot. Tässä luon vain .vue-tiedoston kirjautumista ja rekisteröintiä varten, jossa v-if:n avulla määritetään, ovatko kirjautumislohko- ja rekisteröintilohkoelementit. mukaan lukien, mikä vaikuttaa niiden näyttöön.

Alkuasetukset

v-if="loginShow"为true, v-if="registerShow"为false

Vaihtaa tosi ja epätosi, kun painiketta napsautetaan vaihtaaksesi.

Kun rekisteröinti on onnistunut, vaihda takaisin sisäänkirjautumisosioon.

Mukavuuden ja käyttötottumusten vuoksi, vaikka käyttäjämääritteinä ovat id, käyttäjätunnus, salasana, puhelin ja sukupuoli, rekisteröinnin yhteydessä täytetään vain käyttäjätunnus ja salasana, ja toiminto on yksinkertaisesti toteutettu. Salasanaa ei ole salattu ja se on ei ole tarpeeksi turvallinen Päivitän artikkelin uudelleen kirjoittaakseni turvallisemmasta kirjautumis- ja rekisteröintitavasta sekä siitä, kuinka henkilökohtaisia ​​tietoja täydennetään sisäänkirjautumisen jälkeen.

LoginAndRegister.vue:

  1. <template>
  2. <div class="container">
  3. <div class="login-box" v-if="loginShow">
  4. <!-- 菱形群-->
  5. <div class="decoration1 decoration"></div>
  6. <div class="decoration2 decoration"></div>
  7. <div class="decoration3 decoration"></div>
  8. <div class="decoration4 decoration"></div>
  9. <div class="decoration5 decoration"></div>
  10. <div class="decoration decoration4 decoration6"></div>
  11. <div class="decoration decoration7 decoration2"></div>
  12. <div class="decoration decoration8 decoration3"></div>
  13. <div class="login-title">
  14. <h1>Login</h1>
  15. </div>
  16. <div class="login-part">
  17. <input class="login-input" v-model="username" placeholder="Username" />
  18. <input class="login-input" type="password" v-model="password" placeholder="Password" />
  19. <button class="login-button" @click="login">Login</button>
  20. <div>
  21. 还未注册?点击<a class="change-link" @click="changeToRegister">这里</a>注册
  22. </div>
  23. </div>
  24. </div>
  25. <div class="login-box" v-if="registerShow">
  26. <!-- 菱形群-->
  27. <div class="decoration1 decoration"></div>
  28. <div class="decoration2 decoration"></div>
  29. <div class="decoration3 decoration"></div>
  30. <div class="decoration4 decoration"></div>
  31. <div class="decoration5 decoration"></div>
  32. <div class="decoration decoration4 decoration6"></div>
  33. <div class="decoration decoration7 decoration2"></div>
  34. <div class="decoration decoration8 decoration3"></div>
  35. <div class="login-title">
  36. <h1>Register</h1>
  37. </div>
  38. <div class="login-part">
  39. <input class="login-input" v-model="username" placeholder="Username" />
  40. <input class="login-input" type="password" v-model="password" placeholder="Password" />
  41. <button class="login-button" @click="register">Register</button>
  42. <span class="change-link" @click="changeToLogin">返回登录</span>
  43. </div>
  44. </div>
  45. <!-- <div class="decoration decoration1"></div>-->
  46. <!-- <div class="decoration decoration2"></div>-->
  47. <!-- <div class="decoration decoration3"></div>-->
  48. <!-- <div class="decoration decoration4"></div>-->
  49. </div>
  50. </template>
  51. <script>
  52. import { ref } from 'vue'
  53. import { useRouter } from 'vue-router' // 导入 useRouter
  54. import '../style/Login.css' // 导入css
  55. export default {
  56. name: 'LoginVue',
  57. setup () {
  58. const username = ref('')
  59. const password = ref('')
  60. const phone = ref('')
  61. const loginShow = ref(true)
  62. const registerShow = ref(false)
  63. const router = useRouter()
  64. const changeToRegister = async () => {
  65. loginShow.value = false
  66. registerShow.value = true
  67. }
  68. const changeToLogin = async () => {
  69. loginShow.value = true
  70. registerShow.value = false
  71. }
  72. const login = async () => {
  73. console.log('Login with:', username.value, password.value)
  74. try {
  75. const formData = new FormData()
  76. formData.append('username', username.value)
  77. formData.append('password', password.value)
  78. const response = await fetch('http://localhost:8081/api/user/login', {
  79. method: 'POST',
  80. body: formData
  81. })
  82. const data = await response.json()
  83. if (response.ok) {
  84. console.log('Link success', data)
  85. if (data.code === 200) {
  86. // 登录成功
  87. alert('登录成功!')
  88. await router.push('/home')
  89. } else {
  90. alert(data.msg)
  91. }
  92. } else {
  93. console.error('Link failed', data)
  94. }
  95. } catch (error) {
  96. console.error('Error login', error)
  97. }
  98. }
  99. const register = async () => {
  100. console.log('Register with:', username.value, password.value)
  101. try {
  102. const formData = new FormData()
  103. formData.append('username', username.value)
  104. formData.append('password', password.value)
  105. const response = await fetch('http://localhost:8081/api/user/register', {
  106. method: 'POST',
  107. body: formData
  108. })
  109. const data = await response.json()
  110. if (response.ok) {
  111. if (data.code === 200) {
  112. console.log('Register success', data)
  113. alert('注册成功!')
  114. await changeToLogin()
  115. } else {
  116. console.log('Register failed', data)
  117. alert(data.msg)
  118. }
  119. } else {
  120. console.error('Register failed', data)
  121. }
  122. } catch (error) {
  123. console.error('Error during register', error)
  124. }
  125. }
  126. return { username, password, phone, login, loginShow, registerShow, changeToRegister, register, changeToLogin }
  127. }
  128. }
  129. </script>
  130. <style>
  131. </style>

2) Home.vue

Home.vue on pääsivu, joka hyppää onnistuneen kirjautumisen jälkeen.

Home.vue:

  1. <template>
  2. 首页<br><br>
  3. <button class="login-button" @click="signOut">退出登录</button>
  4. </template>
  5. <script>
  6. import { useRouter } from 'vue-router'
  7. export default {
  8. name: 'HomeVue',
  9. setup () {
  10. const router = useRouter()
  11. const signOut = async () => {
  12. await router.push('/')
  13. }
  14. return { signOut }
  15. }
  16. }
  17. </script>
  18. <style scoped>
  19. </style>

3) reititin

Sivun reititysmääritykset, uudelleenohjaus kirjautumissivulle, kun polku on /, /login on kirjautumissivu ja /home on kotisivu.

index.js:

  1. import { createRouter, createWebHistory } from 'vue-router'
  2. import Login from '../components/LoginAndRegister.vue'
  3. import Home from '../views/Home.vue'
  4. const routes = [
  5. {
  6. path: '/',
  7. redirect: '/login'
  8. },
  9. {
  10. path: '/login',
  11. name: 'Login',
  12. component: Login
  13. },
  14. {
  15. path: '/home',
  16. name: 'Home',
  17. component: Home
  18. }
  19. ]
  20. const router = createRouter({
  21. history: createWebHistory(process.env.BASE_URL),
  22. routes
  23. })
  24. export default router

4) Kirjaudu.css

CSS-suunnittelu kirjautumisrekisteröintisivulle.

Login.css:

  1. *{
  2. margin: 0;
  3. padding: 0;
  4. }
  5. .container{
  6. height: 100vh;
  7. display: flex;
  8. justify-content: center;
  9. align-items: center;
  10. overflow: hidden;
  11. position: relative;
  12. }
  13. .login-box{
  14. background-color: white;
  15. padding: 40px 100px;
  16. border-radius: 8px;
  17. box-shadow: 0 0 5px 1px gainsboro;
  18. position: relative;
  19. }
  20. .login-part{
  21. display: flex;
  22. flex-direction: column;
  23. justify-content: center;
  24. margin-top: 20px;
  25. gap: 20px;
  26. }
  27. .login-input{
  28. width: 250px;
  29. height: 30px;
  30. border-radius: 8px;
  31. }
  32. .login-button{
  33. height: 40px;
  34. border-radius: 8px;
  35. background-color: #2c3e50;
  36. color: white;
  37. transition: 0.5s;
  38. }
  39. .login-button:hover{
  40. background-color: darkcyan;
  41. font-size: 15px;
  42. transition: 0.5s;
  43. }
  44. .login-button:active{
  45. background-color: darkslateblue;
  46. }
  47. .change-link{
  48. color: #00BFFF;
  49. text-decoration: underline;
  50. }
  51. .change-link:hover{
  52. color: cornflowerblue;
  53. }
  54. .decoration {
  55. position: absolute;
  56. width: 200px;
  57. height: 200px;
  58. background: linear-gradient(to left, #FDF5E6, #96CDCD );
  59. clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
  60. z-index: 1;
  61. }
  62. .decoration1 {
  63. top: 150px;
  64. left: -210px;
  65. }
  66. .decoration2 {
  67. top: 20px;
  68. right: -20px;
  69. width: 100px; /* 第二个菱形的大小 */
  70. height: 100px;
  71. background: linear-gradient(to right, #FFF5EE, #E6E6FA);
  72. }
  73. .decoration3 {
  74. top: 50px;
  75. right: -180px;
  76. width: 200px; /* 第三个菱形的大小 */
  77. height: 200px;
  78. background: linear-gradient(to right, #7FFFD4, cadetblue);
  79. }
  80. .decoration4 {
  81. top: 200px;
  82. right: -200px;
  83. width: 500px; /* 第三个菱形的大小 */
  84. height: 500px;
  85. z-index: -1;
  86. clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
  87. background: linear-gradient(to right, #FFFACD, #00BFFF);
  88. }
  89. .decoration5 {
  90. top: -100px;
  91. right: 200px;
  92. width: 400px; /* 第三个菱形的大小 */
  93. height: 400px;
  94. z-index: -1;
  95. clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
  96. background: linear-gradient(to right, #AFEEEE, #00BFFF);
  97. }
  98. .decoration6 {
  99. top: 10px;
  100. right: -680px;
  101. }
  102. .decoration7 {
  103. top: -170px;
  104. right: -500px;
  105. }
  106. .decoration8 {
  107. top: -140px;
  108. right: -655px;
  109. }

5) Kirjautumisrekisteröintisivun näyttö

Timantin muotoiset lohkot on järjestetty satunnaisesti, ja alun perin ne näyttävät tältä:

Myöhemmin lisäsin muutaman vinoneliön muotoisen lohkon ja vaihdoin niiden paikkoja ja värejä.

2. Luo springboot+mysql+mybatis-projekti ja muodosta yhteys tietokantaan

Käytä springboot, mysql, mybatis rakentaaksesi taustaprojektin ja muodostaaksesi yhteyden tietokantaan, viittaus:

idea, spring boot+MySQL+MyBatis projekti luo ja näyttää tietokantataulukon sisällön verkkosivulla_idea näyttää tietokannan verkkosivulla-CSDN-blogi

Täydennys artikkeliin:

Jos set- ja get-menetelmien kirjoittaminen tuntuu hankalalta aina, kun luot entiteettiluokan, voit lisätä seuraavat riippuvuudet tiedostoon pom.xml:

  1. <dependency>
  2. <groupId>org.projectlombok</groupId>
  3. <artifactId>lombok</artifactId>
  4. </dependency>

Käytä sitten entiteettiluokan @Data-merkintää jättääksesi joukon kirjoittamatta ja hankkiaksesi menetelmät:

Prosessi on melkein sama, mutta tällä kertaa luomani tiedot ovat erilaisia. Pääsyynä on se, että käyttäjätaulukon attribuutit ja tiedot ovat muuttuneet (ero ei ole suuri, joten keitto ei muuta lääkettä):

Tapahtui ongelma: maven lataa jatkuvasti riippuvuuksia, mutta vastausta ei tule pitkään aikaan

Jotain meni kuitenkin pieleen projektin luomiseen. Tällä kertaa rakensin sen ensimmäistä kertaa -in, eikä vastausta tullut pitkään aikaan:

Ratkaisu:

Tyhjensin välimuistin ja käynnistin idean uudelleen, mutta sillä ei ollut juurikaan vaikutusta.

Myöhemmin huomasin, että se saattaa johtua siitä, että Maven käyttää oletuksena ulkomaista keskusvarastoa, ja käytin ideana maven-laajennusta, joten latausnopeus olisi erittäin hidas.

Joten latasin mavenin paikallisesti, katso opetusohjelma:

Mavenin lataus- ja asennusopastus (erittäin yksityiskohtainen)_maven-asennus-CSDN-blogi

Lataa ohjeen mukaan ja muokkaa kuvan URL-osoitetta kohdassa maven asennuspolku-&gt;conf-&gt;settings.xml. En kuitenkaan määrittänyt ympäristömuuttujia suoraan ideassa tiedosto-&gt;asetukset-&gt; Build, Execution, Deployment-&gt; Build Tools-&gt; Muuta Mavenissa Mavenin kotipolku paikalliseksi poluksi:

Muutoksen jälkeen latausnopeus on todellakin paljon nopeampi.

Lopullisen taustaprojektin hakemistorakenne on seuraava:

3. Kirjoita sisäänkirjautumisen ja rekisteröinnin taustatoiminnot

1. Kirjautumislogiikka

Hanki käyttöliittymän lähettämät täytetyt tiedot, mukaan lukien käyttäjätunnus ja salasana, ja kysely tietokannan käyttäjätunnuksen ja salasanan perusteella. Jos käyttäjä löytyy, se tarkoittaa, että käyttäjä on olemassa ja käyttäjätunnus ja salasana vastaavat Kirjautuminen onnistui, muuten se epäonnistuu.

2. Rekisteröintilogiikka

Hanki käyttöliittymän välittämät täyttötiedot, mukaan lukien käyttäjätunnus ja salasana, kun olet päättänyt, että syötetyt tiedot eivät ole tyhjiä, etsi käyttäjä ensin tietokannasta käyttäjänimen mukaan epäonnistuu ja palautetaan tiedot, jos niitä ei löydy, käyttäjät voivat rekisteröityä ja lisätä tietueen onnistuneen rekisteröinnin jälkeen.

3. Taustakoodin osa

Niistä resurssit-&gt;mapper-&gt;UserMapper.xml:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  3. "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
  4. <mapper namespace="com.example.demo.mapper.UserMapper" >
  5. <resultMap id="result" type="com.example.demo.entity.User">
  6. <result property="id" column="id" />
  7. <result property="username" column="username" />
  8. <result property="password" column="password" />
  9. <result property="phone" column="phone" />
  10. <result property="gender" column="gender"/>
  11. </resultMap>
  12. <!-- 通过用户名和密码查找对应用户,用于登录-->
  13. <select id="findUserByNameAndPwd" resultMap="result" parameterType="User">
  14. select * from user
  15. where username = #{username}
  16. and password = #{password}
  17. </select>
  18. <!-- 通过用户名查找对应用户,用于注册检验用户名是否已存在-->
  19. <select id="findUserByName" resultMap="result" parameterType="User">
  20. select * from user
  21. where username = #{username}
  22. </select>
  23. <!-- 添加用户-->
  24. <insert id="addUser" parameterType="User">
  25. insert into user (username, password)
  26. values ( #{username}, #{password} )
  27. </insert>
  28. </mapper>

java-&gt;com.example.demo-&gt;mapper-&gt;UserMapper.java:

  1. package com.example.demo.mapper;
  2. import com.example.demo.entity.User;
  3. import org.apache.ibatis.annotations.Mapper;
  4. @Mapper
  5. public interface UserMapper {
  6. // 通过用户名和密码查找对应用户
  7. public User findUserByNameAndPwd(User user);
  8. // 通过用户名查找用户
  9. public User findUserByName(User user);
  10. // 添加用户
  11. public void addUser(User user);
  12. }

java-&gt;com.example.demo-&gt;service-&gt;UserService.java:

  1. package com.example.demo.service;
  2. import com.example.demo.entity.User;
  3. public interface UserService {
  4. // 通过用户名和密码查找对应id
  5. public User findUserByNameAndPwd(User user);
  6. // 通过用户名查找用户
  7. public User findUserByName(User user);
  8. // 添加用户
  9. public void addUser(User user);
  10. }

java-&gt;com.example.demo-&gt;service-&gt;UserServiceImpl.java:

  1. package com.example.demo.service;
  2. import com.example.demo.entity.User;
  3. import com.example.demo.mapper.UserMapper;
  4. import jakarta.annotation.Resource;
  5. import org.springframework.stereotype.Service;
  6. @Service
  7. public class UserServiceImpl implements UserService {
  8. @Resource
  9. private UserMapper userMapper;
  10. // 通过用户名和密码查找对应id
  11. @Resource
  12. public User findUserByNameAndPwd(User user){
  13. return userMapper.findUserByNameAndPwd(user);
  14. }
  15. // 通过用户名查找用户
  16. @Resource
  17. public User findUserByName(User user){
  18. return userMapper.findUserByName(user);
  19. }
  20. // 添加用户
  21. @Resource
  22. public void addUser(User user){
  23. userMapper.addUser(user);
  24. }
  25. }

java-&gt;com.example.demo-&gt;controller-&gt;UserController.java:

  1. package com.example.demo.controller;
  2. import com.example.demo.entity.User;
  3. import com.example.demo.result.Result;
  4. import com.example.demo.service.UserService;
  5. import jakarta.annotation.Resource;
  6. import org.springframework.web.bind.annotation.*;
  7. @RestController
  8. @RequestMapping("/api/user")
  9. public class UserController {
  10. @Resource
  11. UserService userService;
  12. // 登录
  13. @CrossOrigin
  14. @PostMapping(value = "/login")
  15. public Result login(@ModelAttribute("user") User user){
  16. String username=user.getUsername();
  17. String password=user.getPassword();
  18. System.out.println("Login received username: " + username);
  19. System.out.println("Login received password: " + password);
  20. User userCheck = new User();
  21. userCheck.setUsername(username);
  22. userCheck.setPassword(password);
  23. System.out.println(userCheck.getUsername() + " " + userCheck.getPassword());
  24. try{
  25. User findUser = userService.findUserByNameAndPwd(userCheck);
  26. if(findUser != null){
  27. return Result.success(findUser);
  28. }else {
  29. return Result.failure(401,"用户名或密码错误");
  30. }
  31. }catch (Exception e){
  32. return Result.failure(500,"服务器异常");
  33. }
  34. }
  35. // 注册
  36. @CrossOrigin
  37. @PostMapping(value = "/register")
  38. public Result register(@ModelAttribute("user") User user){
  39. // String username = "222";
  40. // String password = "222";
  41. User userCheck = new User();
  42. userCheck.setUsername(user.getUsername());
  43. userCheck.setPassword(user.getPassword());
  44. if(userCheck.getUsername() == null || userCheck.getUsername().isEmpty() || userCheck.getPassword() == null || userCheck.getPassword().isEmpty()){
  45. System.out.println("用户名或密码不可为空");
  46. return Result.failure(201,"用户名和密码不可为空");
  47. }else {
  48. System.out.println("Register received username: " + userCheck.getUsername());
  49. System.out.println("Register received password: " + userCheck.getPassword());
  50. try{
  51. // 先在数据库中查找是否已有用户名相同的用户
  52. User findUser = userService.findUserByName(userCheck);
  53. if(findUser != null){
  54. // 用户名已存在
  55. return Result.failure(202,"用户名已存在!");
  56. }
  57. else {
  58. // 新用户,数据库添加记录
  59. userService.addUser(userCheck);
  60. return Result.success(userCheck);
  61. }
  62. }catch (Exception e) {
  63. return Result.failure(500, "服务器异常");
  64. // }
  65. }
  66. }
  67. }
  68. }

4. Suorita projekti

Etu- ja takapäät ajetaan ja käynnistetään erikseen. Muutin takapään portiksi 8081:ksi Application.propertiesissa, ja etupää on oletusarvo 8080. Joten kun etu- ja takapään projektit on suoritettu onnistuneesti, kirjoita http:/. /localhost:8080 selaimessa , tarkista se kehittäjätyökalujen verkosta, muodosta yhteys taustajärjestelmään, ja kirjautuessasi sisään ja rekisteröityessäsi testisyöttöä varten, voit palauttaa onnistuneesti erilaisia ​​kehotteita ja ponnahduskehotteita:

Onnistuneen kirjautumisen jälkeen: