手把手帮助你通过Vue+Springboot+MybatisPlus实现一个简单的登录注册页面,0基础

2023-11-18

创建前端vue项目

首先通过脚手架创建vue文件夹

前提: 安装好node.js软件 ,安装好后,通过node -V 查看版本号 , npm -V查看npm版本

通过命令安装脚手架 npm install -g @vue/cli -g代表全局安装,-s代表本地安装

准备好后,创建一个文件夹来存放该项目的前后端文件,最好不要有中文路径(有些编译器不允许),

这里就创建文件夹叫test

然后打开命令提示符(快捷键 windows+r 并输入cmd),进入web-api文件目录(cd进入,..cd退出)

就可以通过命令进行创建vue项目了

  1. vue create + 项目目录名称(web-api)

  1. 选择该选项 Manually select features enter进入下一个选择

  1. 选择 Babel Router Vuex 三个选项 空格选中, enter进入下一个选择

  1. 这里选择的是vue3 enter进入下一个选择

  1. 选y In package.json n 就创建好一个vue项目了

查看项目是否能正常运行,运行以下两个命令行 $ cd web-api $ npm run serve

运行成功后,进入网页查看 http://localhost:8080/,页面如下,则成功创建

在idea中打开该项目

打开后,在web-api下创建一个Web文件存放前端项目,将下图中的文件移动到Web文件夹中

点击该项添加前端运行快捷键

将Name,Script改为serve package.json应该是该包所在的路径,完成后点击应用即可

设置运行自动打开,在package.json文件第六行改为:"serve": "vue-cli-service serve --open",

解决办法:将Web\node_modules\@vue\cli-service\lib\commands\serve.js文件第11行的

host: '0.0.0.0' 改为 host: 'localhost' 就可以解决了

前端多余文件的删除

将src下 componenets文件夹下的HelloWorld.vue文件

views文件夹下的AboutView.vue,Homeview.vuewen文件删除

并在views下新建一个Login.vue页面

删除后这时会报错,再把App.vue中的删除,改为

<template>
  <router-view/>
</template>

<style>

</style>

同时删除 src/route/index.js文件中的home和about路由,并加上Login的路由

import { createRouter, createWebHistory } from 'vue-router'
import Login from "../views/Login";

const routes = [
    {
    path: '/',
  },
  {
    path: '/login',
    name: 'Login',
    component: Login
  },
]

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
})

export default router

简单去除基础样式,在src assets文件下创建文件夹css以及在css下创建global.css文件

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;     //盒内元素
}

在main.js文件中引入global.css文件,同时将element-plus,中文等引入进去

注意要进入到Web文件夹下引入才可,这里save是本地安装的意思

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

// 引入css样式
import '@/assets/css/global.css'

// 引入element-plus
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

// 引入中文
import 'dayjs/locale/zh-cn'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'

createApp(App).use(store).use(router).use(ElementPlus, {locale: zhCn,size:'small'}).mount('#app')

编写Login.vue页面

因为下述用到了背景图片,在assets下新增一个img文件夹,并添加照片即可(名字需要一致)

<template>
  <div id="login">
    <div id="subForm" >
      <div style="text-align: center;color: black;font-weight: bold;font-size: 25px;margin: 35px auto">欢迎登录</div>
      <el-form :model="form" label-width="120px" style="margin-left: 10%" ref="form" :rules="rules">
        <el-form-item label="用户名" prop="username">
          <el-input style="width: 60%" placeholder="请输入账号" v-model="form.username" />
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input style="width: 60%" placeholder="请输入密码" v-model="form.password" show-password="true" />
        </el-form-item>
        <el-form-item style="margin-top: 30px;margin-left: 10px">
          <el-button type="primary"  @click="login">登录</el-button>
          <el-button type="danger" @click="register">点击注册</el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script>

export default {
  name: "Login",
  data() {
    return {
      form: {},
      rules:{
        username: [
          {required:true,message:'请输入用户名',trigger:'blur'},
          // {min: 2, max: 11, message: '长度在 3 到 5 个字符', trigger: 'blur'}
        ],
        password: [
          {required:true,message:'请输入密码',trigger:'blur'},

          {min: 6, max: 11, message: '长度在 6 到 11 个字符', trigger: 'blur'}
        ],
      },
    }
  },
  methods: {
    login() {
      this.$refs['form'].validate((valid) => {
        if (valid) {
          this.$message({
            type: "success",
            message: "登录成功"
          })
            this.router.push("/")
        }
      })
    }
  },
    register() {
      this.$router.push("/register")
  }
}
</script>

<style scoped>
#login {
  position: relative;
  width: 100%;
  height: 100vh;
  background-image: url('../assets/img/bg.jpg');
  background-size: 100%;
  background-repeat: no-repeat;
  overflow: hidden;
}
#subForm {
  position: absolute;
  /*width: 500px;*/
  /*min-height: 300px;*/
  width: 400px;
  min-height:280px;
  margin:200px auto;
  top:0;
  left:539px;
  background: rgba(255,250,240,.5);
  box-sizing:border-box;
  border-radius: 30px;
  box-shadow: 0px 15px 25px rgba(0,0,0,.5);
  opacity: 0.75;

}
</style>

创建Register.vue页面

在index.js文件中引入路由

import { createRouter, createWebHistory } from 'vue-router'
import Login from "../views/Login";
import Register from "../views/Register";

const routes = [
  {
    path: '/',
  },
  {
    path: '/login',
    name: 'Login',
    component: Login
  },
  {
    path: '/register',
    name: 'Register',
    component: Register
  },
]

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
})

export default router
<template>
  <div id="login">
    <div id="subForm" >
      <div style="text-align: center;color: black;font-weight: bold;font-size: 25px;margin: 35px auto">免费注册账号</div>
      <el-form :model="form" label-width="120px" style="margin-left: 10%" ref="form" :rules="rules">
        <el-form-item label="账号" prop="username">
          <el-input style="width: 70%" placeholder="请输入账号" v-model="form.username" />
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input style="width: 70%" placeholder="请输入密码" v-model="form.password" show-password="true" />
        </el-form-item>
        <el-form-item label="确认密码" prop="confirm">
          <el-input style="width: 70%" v-model="form.confirm" show-password placeholder="请再次输入密码"></el-input>
        </el-form-item>

        <el-form-item label="昵称" prop="nickName">
          <el-input style="width: 70%" placeholder="请输入昵称" v-model="form.nickName"  />
        </el-form-item>
        <el-form-item label="年龄" prop="age">
          <el-input style="width: 70%" placeholder="请输入年龄" v-model="form.age"  />
        </el-form-item>
        <el-form-item label="性别" prop="sex">
          <el-radio-group  v-model="form.sex">
            <el-radio label="男" />
            <el-radio label="女" />
            <el-radio label="未知" />
          </el-radio-group>
        </el-form-item>
        <el-form-item label="地址" prop="address">
          <el-input style="width: 70%" type="textarea" placeholder="请输入地址" v-model="form.address"  />
        </el-form-item>

        <el-form-item style="margin-top: 30px;">

          <el-button style="width: 70%" type="danger" @click="register">点击注册</el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script>
// import request from "../utils/request";

export default {
  name: "Register",
  data() {
    return {
      form : {},
      rules: {
        username: [
          {required:true,message:'请输入用户名',trigger:'blur'},
          // {min: 2, max: 11, message: '长度在 3 到 5 个字符', trigger: 'blur'}
        ],
        password: [
          {required:true,message:'请输入密码',trigger:'blur'},

          {min: 6, max: 11, message: '长度在 6 到 11 个字符', trigger: 'blur'}
        ],
        confirm: [
          {required:true,message:'请再次输入密码',trigger:'blur'}
        ],
        nickName: [
          {required: true, message: '请输入昵称', trigger: 'blur'},
          {min: 2, max: 11, message: '长度在 3 到 5 个字符', trigger: 'blur'}
        ],
        age: [
          {required: true, message: '请输入年龄', trigger: 'blur'},
          {min: 1, max: 3, message: '长度在 3 到 5 个字符', trigger: 'blur'}
        ],
        sex: [
          {required: true, message: '请选择性别', trigger: 'change'}
        ],
        address: [
          {required: true, message: '请输入地址', trigger: 'blur'},
          {min: 2, message: '长度要大于2个字符', trigger: 'blur'}
        ]
      }
    }
  },
  methods:{
    register() {
      if (this.form.password !== this.form.confirm){
        this.$message({
          type: "error",
          message: "两次输入密码不一致"
        })
        return
      }
      this.$refs['form'].validate((valid) => {
        if (valid) {
          this.$message({
              type: "success",
            message: "注册成功"
          })
              this.$router.push("/login")   //注册成功后进行页面的跳转到login
        }else {
          this.$message({
            type: "error",
            message: "请将信息输入完毕"
          })
        }
      })

    }
  }
}
</script>

<style scoped>
#login {
  position: relative;
  width: 100%;
  height: 100vh;
  background-image: url('../assets/img/bg.jpg');
  background-size: 100%;
  background-repeat: no-repeat;
  overflow: hidden;
}
#subForm {
  position: absolute;
  /*width: 500px;*/
  /*min-height: 300px;*/
  width: 400px;
  min-height:280px;
  margin:150px auto;
  top:0;
  left:539px;
  background: rgba(255,250,240,.5);
  box-sizing:border-box;
  border-radius: 30px;
  box-shadow: 0px 15px 25px rgba(0,0,0,.5);
  opacity: 0.75;

}
</style>

这里可以进行登录页面和注册页面间的切换了

接下来进行后端登录,注册的接口开发

通过网站 https://start.spring.io/ 进行springboot项目的创建

springboot项目版本随便

选好后创建后会下载一个demo.zip包,先放着

然后通过idea在web-api文件夹下创建一个maven项目 new Module ---》 maven ---》next ----finsh

然后将生成的src和pom.xml删除

将demo.zip中的src和pom.xml复制到api文件夹中,test文件夹可删可不删

这里用到的依赖pom.xml,等待依赖加载完成

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.5.2</version>
      <relativePath/> <!-- lookup parent from repository -->
   </parent>
   <groupId>com.example</groupId>
   <artifactId>demo</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <name>demo</name>
   <description>Demo project for Spring Boot</description>
   <properties>
      <java.version>1.8</java.version>
   </properties>
   <dependencies>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
<!--      <dependency>-->
<!--         <groupId>org.mybatis.spring.boot</groupId>-->
<!--         <artifactId>mybatis-spring-boot-starter</artifactId>-->
<!--         <version>3.0.0</version>-->
<!--      </dependency>-->
      <!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
      <dependency>
         <groupId>org.mybatis.spring.boot</groupId>
         <artifactId>mybatis-spring-boot-starter</artifactId>
         <version>2.2.0</version>
      </dependency>


<!--      <dependency>-->
<!--         <groupId>com.mysql</groupId>-->
<!--         <artifactId>mysql-connector-j</artifactId>-->
<!--         <scope>runtime</scope>-->
<!--      </dependency>-->
      <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
         <scope>runtime</scope>
      </dependency>
      <dependency>
         <groupId>org.projectlombok</groupId>
         <artifactId>lombok</artifactId>
         <optional>true</optional>
      </dependency>
<!--      <dependency>-->
<!--         <groupId>org.springframework.boot</groupId>-->
<!--         <artifactId>spring-boot-starter-test</artifactId>-->
<!--         <scope>test</scope>-->
<!--      </dependency>-->
<!--      <dependency>-->
<!--         <groupId>org.springframework.boot</groupId>-->
<!--         <artifactId>spring-boot-devtools</artifactId>-->
<!--         <scope>runtime</scope>-->
<!--         <optional>true</optional>-->
<!--      </dependency>-->
      <!--      分页插件-->
      <dependency>
         <groupId>com.baomidou</groupId>
         <artifactId>mybatis-plus-boot-starter</artifactId>
         <version>3.4.3.1</version>
      </dependency>

      <dependency>
         <groupId>cn.hutool</groupId>
         <artifactId>hutool-all</artifactId>
         <version>5.7.3</version>
      </dependency>
   </dependencies>

   <build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
               <excludes>
                  <exclude>
                     <groupId>org.projectlombok</groupId>
                     <artifactId>lombok</artifactId>
                  </exclude>
               </excludes>
            </configuration>
         </plugin>
      </plugins>
   </build>

</project>

新建数据库,在数据库创建好以及引入好之后且依赖导入完成就可以启动springboot项目了

引入数据库application.properties

#设置后台端口号
server.port=9090     
#进行数据库的连接
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#springboot-vue-test为所要连接的数据库
spring.datasource.url=jdbc:mysql://localhost:3306/web-api?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2b8
#所要数据库的用户名和密码
spring.datasource.username=root
spring.datasource.password=92645664

#spring.jackson.date-format=yyyy-MM-dd

打开网页localhost:9090页面如下则成功了

好了之后进行相关插件的引入,一般放置于common文件夹下

引入mybatisplus插件,同时在pom.xml文件中导入mybatisplus依赖

package com.example.demo.common;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 *  mybatis-plus 分页插件
 */
@Configuration
@MapperScan("com.example.demo.mapper")
public class MybatisPlusConfig {

    /**
     * 分页插件
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
                                                      //        注意改为DbTybe.MYSQL
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }

}

别忘了在pom.xml文件中导入mybatis依赖哦

<dependency>
   <groupId>com.baomidou</groupId>
   <artifactId>mybatis-plus-boot-starter</artifactId>
   <version>3.4.3.1</version>
</dependency>

在common文件夹中引入Result.java(名称自定义),该文件作用是返回前台数据的包装类(返回前台数据并将其进行包装),相当于一个自定义的数据返回类

package com.example.demo.common;

public class Result<T> {
    private String code;
    private String msg;
    private T data;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public Result() {
    }

    public Result(T data) {
        this.data = data;
    }

    public static Result success() {
        Result result = new Result<>();
        result.setCode("0");
        result.setMsg("成功");
        return result;
    }

    public static <T> Result<T> success(T data) {
        Result<T> result = new Result<>(data);
        result.setCode("0");
        result.setMsg("成功");
        return result;
    }

    public static Result error(String code, String msg) {
        Result result = new Result();
        result.setCode(code);
        result.setMsg(msg);
        return result;
    }
}

引入好需要用到的之后,就可以开始进行接口的编写,这里先写登录接口。

首先在entity创建实体User.java

@Data是属于lombok的注解,可以自动生成获取实体类的get,set方法,就可以省去自己写get。set方法

package com.example.demo.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@Data
@TableName("user")
public class User {
    @TableId(type = IdType.AUTO)   //设置id自增
    private Integer id;
    private String username;
    private String password;
}

接下来创建UserMapper接口,该接口继承BaseMapper

package com.example.demo.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.entity.User;

public interface UserMapper extends BaseMapper<User> {
}

然后创建UserController.java

引入@RestController 该注解的意思是

引入@RequestMapping("/user") 该注解的意思是

package com.example.demo.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user")
public class UserController {
}

@Resource UserMapper userMapper; 将UserMapper注入到UserController.java中

package com.example.demo.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user")
public class UserController {
      @Resource
        UserMapper userMapper;
}

编写login接口

package com.example.demo.controller;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.example.demo.common.Result;
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
@RequestMapping("/user")
public class UserController {
    @Resource
    UserMapper userMapper;
    @PostMapping("/login")
    public Result<?> login(@RequestBody User user){
        //将输入的数据与数据库进行匹配,看是否存在
        User haveUser = userMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getUsername, user.getUsername())
                .eq(User::getPassword, user.getPassword()));
        if (haveUser == null) {
            return Result.error("100","用户或密码错误");
        }
        return Result.success();
    }
}

这里在数据库user表创建了两条数据如下

数据的前后端交互采用axios,因此在web文件夹下通过命令行

npm install axios -save 引入axios插件

并在Web文件夹下创建一个对axios封装的request.js文件,放在一个新建的文件夹下,文件夹任意命名

import axios from 'axios'

const request = axios.create({
    baseURL: '/api',  // 注意!! 这里是全局统一加上了 '/api' 前缀,也就是说所有接口都会加上'/api'前缀在,页面里面写接口的时候就不要加 '/api'了,否则会出现2个'/api',类似 '/api/api/user'这样的报错,切记!!!
    timeout: 5000
})

// request 拦截器
// 可以自请求发送前对请求做一些处理
// 比如统一加token,对请求参数统一加密
request.interceptors.request.use(config => {
    config.headers['Content-Type'] = 'application/json;charset=utf-8';

    // config.headers['token'] = user.token;  // 设置请求头
    return config
}, error => {
    return Promise.reject(error)
});

// response 拦截器
// 可以在接口响应后统一处理结果
request.interceptors.response.use(
    response => {
        let res = response.data;
        // 如果是返回的文件
        if (response.config.responseType === 'blob') {
            return res
        }
        // 兼容服务端返回的字符串数据
        if (typeof res === 'string') {
            res = res ? JSON.parse(res) : res
        }
        return res;
    },
    error => {
        console.log('err' + error) // for debug
        return Promise.reject(error)
    }
)


export default request

到这里就可以去login.vue页面添加相关的数据请求了

<template>
  <div id="login">
    <div id="subForm" >
      <div style="text-align: center;color: black;font-weight: bold;font-size: 25px;margin: 35px auto">欢迎登录</div>
      <el-form :model="form" label-width="120px" style="margin-left: 10%" ref="form" :rules="rules">
        <el-form-item label="用户名" prop="username">
          <el-input style="width: 60%" placeholder="请输入账号" v-model="form.username" />
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input style="width: 60%" placeholder="请输入密码" v-model="form.password" show-password="true" />
        </el-form-item>
        <el-form-item style="margin-top: 30px;margin-left: 10px">
          <el-button type="primary"  @click="login">登录</el-button>
          <el-button type="danger" @click="register">点击注册</el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script>

import request from "../utils/request";

export default {
  name: "Login",
  data() {
    return {
      form: {},
      rules:{
        username: [
          {required:true,message:'请输入用户名',trigger:'blur'},
          // {min: 2, max: 11, message: '长度在 3 到 5 个字符', trigger: 'blur'}
        ],
        password: [
          {required:true,message:'请输入密码',trigger:'blur'},

          {min: 6, max: 11, message: '长度在 6 到 11 个字符', trigger: 'blur'}
        ],
      },
    }
  },
  methods: {
    login() {
      this.$refs['form'].validate((valid) => {
        if (valid) {
          request.post("/user/login",this.form).then(res =>{
            if (res.code == '0') {

              this.$message({
                type: "success",
                message: "登录成功"
              })
              this.$router.push("/")
            }else {
              this.$message({
                type: "error",
                message: res.msg
              })
            }

          })
        }
      })
    },
    register() {
      this.$router.push("/register")
    }
  }
  // data() {
  //   return {
  //     form : {},
  //     rules:{
  //       username: [
  //         {required:true,message:'请输入用户名',trigger:'blur'},
  //         // {min: 2, max: 11, message: '长度在 3 到 5 个字符', trigger: 'blur'}
  //       ],
  //       password: [
  //         {required:true,message:'请输入密码',trigger:'blur'},
  //
  //         {min: 6, max: 11, message: '长度在 6 到 11 个字符', trigger: 'blur'}
  //       ],
  //     }
  //   }
  // },
  // methods:{
  //   login() {
  //     this.$refs['form'].validate((valid) => {
  //       if (valid) {
  //         request.post("/user/login",this.form).then(res => {
  //           if (res.code === '0') {
  //             this.$message({
  //               type: "success",
  //               message: "登录成功"
  //             })
  //             console.log("在这里是res")
  //             console.log(res)
  //             sessionStorage.setItem("user",JSON.stringify(res.data))  //缓存用户信息
  //             this.$router.push("/")   //登录成功后进行页面的跳转
  //           }else {
  //             this.$message({
  //               type: "error",
  //               message: res.msg
  //             })
  //           }
  //         })
  //       }
  //     })
  //   },
  //   register() {
  //     this.$router.push("/register")
  //   }
  // }
}
</script>

<style scoped>
#login {
  position: relative;
  width: 100%;
  height: 100vh;
  background-image: url('../assets/img/bg.jpg');
  background-size: 100%;
  background-repeat: no-repeat;
  overflow: hidden;
}
#subForm {
  position: absolute;
  /*width: 500px;*/
  /*min-height: 300px;*/
  width: 400px;
  min-height:280px;
  margin:200px auto;
  top:0;
  left:539px;
  background: rgba(255,250,240,.5);
  box-sizing:border-box;
  border-radius: 30px;
  box-shadow: 0px 15px 25px rgba(0,0,0,.5);
  opacity: 0.75;

}
</style>

此时去页面进行登录,报以下错误(跨域问题)

解决方法,在Web文件夹下创建vue.config.js

// 跨域配置
module.exports = {
    devServer: {                //记住,别写错了devServer//设置本地默认端口  选填
        port: 8080,
        proxy: {                 //设置代理,必须填
            '/api': {              //设置拦截器  拦截器格式   斜杠+拦截器名字,名字可以自己定
                target: 'http://localhost:9090',     //代理的目标地址
                changeOrigin: true,              //是否设置同源,输入是的
                pathRewrite: {                   //路径重写
                    '^/api': ''                     //选择忽略拦截器里面的内容
                }
            }
        }
    }
}

此时去重新登录,就可以了,效果图如下,到这里一个简单的登录接口就写好了

接下来就可以进行注册页面的接口编写了

package com.example.demo.controller;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.example.demo.common.Result;
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
@RequestMapping("/user")
public class UserController {
    @Resource
    UserMapper userMapper;
    //登录接口
    @PostMapping("/login")
    public Result<?> login(@RequestBody User user){
        //将输入的数据与数据库进行匹配,看是否存在
        User haveUser = userMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getUsername, user.getUsername())
                .eq(User::getPassword, user.getPassword()));
        if (haveUser == null) {
            return Result.error("-1","用户或密码错误");
        }
        return Result.success();
    }

    //注册接口
    @PostMapping("/register")
    public Result<?> register(@RequestBody User user){
        //将输入的数据与数据库进行匹配,看是否存在
        User haveUser = userMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getUsername, user.getUsername()));
        if (haveUser != null) {
            return Result.error("-1","用户已经存在");
        }
        //如果不存在,则将该注册号插入进去
        userMapper.insert(user);
        return Result.success();
    }
}

后端接口写好后,就可以去为前端Register.vue添加相应的接口请求了

<template>
  <div id="login">
    <div id="subForm" >
      <div style="text-align: center;color: black;font-weight: bold;font-size: 25px;margin: 35px auto">免费注册账号</div>
      <el-form :model="form" label-width="120px" style="margin-left: 10%" ref="form" :rules="rules">
        <el-form-item label="账号" prop="username">
          <el-input style="width: 70%" placeholder="请输入账号" v-model="form.username" />
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input style="width: 70%" placeholder="请输入密码" v-model="form.password" show-password="true" />
        </el-form-item>
        <el-form-item label="确认密码" prop="confirm">
          <el-input style="width: 70%" v-model="form.confirm" show-password placeholder="请再次输入密码"></el-input>
        </el-form-item>
        <el-form-item label="年龄" prop="age">
          <el-input style="width: 70%" placeholder="请输入年龄" v-model="form.age"  />
        </el-form-item>
        <el-form-item label="性别" prop="sex">
          <el-radio-group  v-model="form.sex">
            <el-radio label="男" />
            <el-radio label="女" />
            <el-radio label="未知" />
          </el-radio-group>
        </el-form-item>
        <el-form-item label="地址" prop="address">
          <el-input style="width: 70%" type="textarea" placeholder="请输入地址" v-model="form.address"  />
        </el-form-item>

        <el-form-item style="margin-top: 30px;">

          <el-button style="width: 70%" type="danger" @click="register">点击注册</el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script>

import request from "../utils/request";

export default {
  name: "Register",
  data() {
    return {
      form : {},
      rules: {
        username: [
          {required:true,message:'请输入用户名',trigger:'blur'},
          // {min: 2, max: 11, message: '长度在 3 到 5 个字符', trigger: 'blur'}
        ],
        password: [
          {required:true,message:'请输入密码',trigger:'blur'},

          {min: 6, max: 11, message: '长度在 6 到 11 个字符', trigger: 'blur'}
        ],
        confirm: [
          {required:true,message:'请再次输入密码',trigger:'blur'}
        ],
        age: [
          {required: true, message: '请输入年龄', trigger: 'blur'},
          {min: 1, max: 3, message: '长度在 3 到 5 个字符', trigger: 'blur'}
        ],
        sex: [
          {required: true, message: '请选择性别', trigger: 'change'}
        ],
        address: [
          {required: true, message: '请输入地址', trigger: 'blur'},
          {min: 2, message: '长度要大于2个字符', trigger: 'blur'}
        ]
      }
    }
  },
  methods:{
    register() {
      if (this.form.password !== this.form.confirm){
        this.$message({
          type: "error",
          message: "两次输入密码不一致"
        })
        return
      }
      this.$refs['form'].validate((valid) => {
        if (valid) {
          request.post("/user/register",this.form).then(res => {
            if (res.code === '0') {

              this.$message({
                type: "success",
                message: "注册成功"
              })
              this.$router.push("/login")   //登录成功后进行页面的跳转
            }else {

              this.$message({
                type: "success",
                message: res.msg
              })

            }
          })
        }else {
          this.$message({
            type: "error",
            message: "请将信息输入完毕"
          })
        }
      })

    }
  }
}
</script>

<style scoped>
#login {
  position: relative;
  width: 100%;
  height: 100vh;
  background-image: url('../assets/img/bg.jpg');
  background-size: 100%;
  background-repeat: no-repeat;
  overflow: hidden;
}
#subForm {
  position: absolute;
  /*width: 500px;*/
  /*min-height: 300px;*/
  width: 400px;
  min-height:280px;
  margin:150px auto;
  top:0;
  left:539px;
  background: rgba(255,250,240,.5);
  box-sizing:border-box;
  border-radius: 30px;
  box-shadow: 0px 15px 25px rgba(0,0,0,.5);
  opacity: 0.75;

}
</style>

因为注册字段一般不止用户名和密码,所以数据库较前面额外添加几个数据(与注册表进行相对应或者比注册表字段多),如下

与此同时,在User.java的entity实体类中添加相对应字段

package com.example.demo.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@Data
@TableName("user")
public class User {
    @TableId(type = IdType.AUTO)   //设置id自增
    private Integer id;
    private String username;
    private String password;
    private Integer age;
    private String sex;
    private String address;
}

完成后,点击注册如下图所示

结束

到这里就结束了,可能会有点杂,希望多多理解。如果需要源码,请自行提取。文件里就不放sql文件了,跟着创建一下就行了。

链接:https://pan.baidu.com/s/1JkMXIumxoONW3uU8bfsvjg?pwd=941a

提取码:941a

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

手把手帮助你通过Vue+Springboot+MybatisPlus实现一个简单的登录注册页面,0基础 的相关文章

随机推荐

  • HyDE、UDAPDR(LLM大模型用于信息检索)

    本篇博文继续整理LLM在搜索推荐领域的应用 往期文章请往博主主页查看更多 Precise Zero Shot Dense Retrieval without Relevance Labels 这篇文章主要做zero shot场景下的稠密检索
  • 雷军的代码像诗一样优雅(94年写的),网友直呼:跪着读完!

    点击上方 码农突围 马上关注 这里是码农充电第一站 回复 666 获取一份专属大礼包 真爱 请设置 星标 或点个 在看 程序员晒贴 94年雷军写的代码水平如何 网友直呼 跪着读完 雷军曾自夸自己写的代码像诗一样优雅 网友感觉这雷军写的94年
  • 接口自动化测试框架-httprunner V2.x中文使用手册-快速上手

    本文将通过一个简单的示例来展示 HttpRunner 的核心功能使用方法 案例介绍 该案例作为被测服务 主要有两类接口 权限校验 获取 token 支持 CRUD 操作的 RESTful APIs 所有接口的请求头域中都必须包含有效的 to
  • 2023年最佳JavaScript框架:React、Vue、Angular和Node.js的比较

    文章目录 React 构建用户界面的首选 Vue 简单优雅的前端框架 Angular Google支持的全面框架 Node js 服务器端的JavaScript运行环境 比较不同框架的优势与劣势 React Vue Angular Node
  • 思考外语学习的底层逻辑(以英语、法语为例)

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 目录 前言 一 英语 1 学习历程 2 英语学习的心得 3 理论检验 持续更新 二 法语 1 学习历程 2 读入数据 总结 前言 提示 这里谈谈自己为什么要写这篇博客 自己从
  • 洛谷 P1008 [NOIP1998 普及组] 三连击

    题目链接 https www luogu com cn problem P1008 include
  • 出现错误代码0xc000007b,应用程序无法正常启动的解决方法

    很多用户运行安装软件及运行软件时 或是在玩大型游戏时 会出现电脑报错 0xc000007b应用程序无法正常启动 导致错误代码0xc000007b的原因有很多 驱动人生整理了常见的原因 也为大家提供相应的解决方法 错误代码0xc000007b
  • 8.压缩打包类+文件查找类命令

    个人简介 作者简介 大家好 我是W chuanqi 一个编程爱好者 个人主页 W chaunqi 支持我 点赞 收藏 留言 愿你我共勉 若身在泥潭 心也在泥潭 则满眼望去均是泥潭 若身在泥潭 而心系鲲鹏 则能见九万里天地 文章目录 压缩解压
  • 思维导图系列——计算机网络

    思维导图系列 操作系统 思维导图为博主期末复习亲自整理而成的 知识点覆盖全 可直接看思维导图复习 包含注解 图示等 觉得对你有帮助 不妨一键三连哦 链接见文末 参考书目 计算机网络 第7版 谢希仁 系列文章直达 思维导图系列 计算机网络 添
  • 墨者靶场—SQL手工注入漏洞测试(MySQL数据库)

    0x00 前言 学SQL注入也有一段时间了 找了一个在线靶场 这个题目基本上学会最基本的注入原理和方法都能拿下 废话就不多说了 直接来演示吧 菜鸟渗透 大佬勿喷 0x01 过程 首先我们先稍微看一下题目 通过题目我们可以看出靶场环境是Ngi
  • python水仙花数的编程讲解_Python语言生成水仙花数代码示例

    水仙花数是指一个 n 位数 n 3 它的每个位上的数字的 n 次幂之和等于它本身 本文将通过Python代码实现打印水仙花数 具体如下 水仙花数 narcissistic number 水仙花数是指一个 n 位数 n 3 它的每个位上的数字
  • 如何彻底卸载Anaconda?

    文章目录 0 前言 1 解决方案 1 1方案1 1 2方案2 2 参考文档 0 前言 本机Win10 最好的参考文档是官方文档Uninstalling Anaconda 除此以外 再辅助以其他文档 就能达到如标题所示的目的 整个删除过程不难
  • Unity手游资源修改流程

    最近接到一个Android手游汉化需求 研究了一下 特此记录 开发环境 AssetStudioGUI 该软件可解析 定位压缩后的Unity 资源 下载 https github com Perfare AssetStudio AssetBu
  • 攻防世界-Web新手区- simple_php

    攻防世界 Web新手区 simple php 题目链接 https adworld xctf org cn challenges details hash 97ccaf1c b0ba 4152 88c1 10da78135303 2 tas
  • 通过wiki进行企业内部的知识共享

    其实企业内部的知识共享是一个很复杂的问题 每个人都有自己的经验和Key Knowledge 每次开发也能积累到很多有用的开发经验或者教训 可是怎样才能进行有效的知识共享呢 一个完善的知识共享系统应该具有以下几种特性 易于使用的界面 好的知识
  • 突如其来的C#重新学习(2)

    突如其来的C 重新学习 2 关于Main入口点的问题 Main在C 中不能单独声明 所以必须声明在同一个类中 而且必须声明静态方法 返回可以是void或者int 正常执行应当返回0 对于一个命名空间之内有很多的类的情况下 就可以手动选择从哪
  • 前端网页设置视频背景

    视频设置自动播放 循环播放 静音 一定要设置静音不设置静音的话不会自动播放 video元素设置width 100 height auto 如果height设置100 的话 定位之后会看不到
  • pycharm常用快捷键及快捷键自定义修改

    一 常用快捷键 编辑类 Ctrl D 复制选定的区域或行 Ctrl Y 删除选定的行 Ctrl Alt L 代码格式化 Ctrl Alt O 优化导入 去掉用不到的包导入 Ctrl 鼠标 简介 进入代码定义 Ctrl 行注释 取消注释 Ct
  • 关闭WIN10的wsappx进程服务

    关闭原因 打开电脑登录系统后 发现wsappx进程服务占用CPU极高 并且一直没有降低 如下图所示 解决办法 将以下注册表的值由3修改为4重启系统即可 计算机 HKEY LOCAL MACHINE SYSTEM CurrentControl
  • 手把手帮助你通过Vue+Springboot+MybatisPlus实现一个简单的登录注册页面,0基础

    创建前端vue项目 首先通过脚手架创建vue文件夹 前提 安装好node js软件 安装好后 通过node V 查看版本号 npm V查看npm版本 通过命令安装脚手架 npm install g vue cli g代表全局安装 s代表本地