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

创建前端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/1Y13U_TAxoRZCSxYaiKcnFA?pwd=mbs1 
提取码:mbs1 
 

  • 8
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
VueSpringBoot打造假日旅社管理系统》课程,将讲解如何使用VueSpringBoot开发这个项目,手把手演示开发流程!附赠源码、文档、数据库脚本等全部资料,提供售后答疑。 课程简介本课程讲解的是《基于 VueSpringBoot 的假日旅社管理系统》,该系统支持民宿档案、民宿新闻、民宿预定、民宿评论这四大核心业务,适用于乡村民宿企业的民宿预定业务。系统给每个民宿档案提供一个唯一标识,对民宿预定、评论等各个环节进行快速批量的数据采集,确保游客及时掌握景区民宿的真实数据,方便游客进行民宿预定。另外系统还包括员工管理、组织机构管理、文件管理、权限管理功能,给旅社企业提供更个性化的民宿管理模式。假日旅社管理系统采用了基于角色的访问控制,角色和菜单关联,一个角色可以配置多个菜单权限;然后再将用户和角色关联,一位用户可以赋予多个角色。这样用户就可以根据角色拿到该有的菜单权限,更方便旅社企业的管理人员进行权限管控。   软件技术选型前端VueVue 是构建前端界面的核心框架,本系统采用 2.6.14 版本。View UI:基于 Vue.js2.0 的组件库,本系统采用 4.7.0 版本。后端Spring Boot:构建系统核心逻辑的后端框架,本系统采用 2.7.0 版本。MyBatis / MyBatis Plus:后端连接数据库的框架,本系统采用 3.5.2 版本。数据库MySQL:本项目的主数据库,本系统采用 8.0.29 版本。Redis:本系统采用基于 Windows 版本的 Redis,用于图形验证码和用户菜单权限的临时存储,采用了 5.0.14 版本。开发环境VsCode:项目前端的开发工具,使用版本为 1.68.0。IntelliJ IDEA :项目后端的开发工具,使用版本为 2021.3.2。Jdk:Java 的开发环境,使用版本为 17.0.3.1。Maven:后端项目的打包工具,使用版本为 3.6.2。NodeJs:前端项目的开发环境,使用版本为 16.13.0。 软件架构分析基于 VueSpringBoot 的假日旅社管理系统包括了系统基础模块、民宿档案模块、民宿新闻模块、民宿预定模块、民宿评论模块这五大功能模块,其架构如下图所示。  接下来,分别对五大模块进行详细介绍。系统基础模块系统基础模块,是用于支撑假日旅社管理系统的正常运行,这个模块包括了登陆注册模块、员工部门管理、菜单权限管理等。假日旅社管理系统支持用户使用账号、密码和图形验证码登陆,操作界面如下图所示。  假日旅社管理系统支持用户使用手机号、姓名、密码和图形验证码注册,操作界面如下图所示。 用户成功进入系统后,可进入到基于 VueSpringBoot 的假日旅社管理系统的首页,首页展示了当前登陆的地址、现在的时间和用户配置的常用模块,如下图所示。 接着用户点击左侧的用户管理,即可进入用户管理模块,用户管理模块的首页如下图所示。 用户可以在这个模块对系统登陆用户的档案进行维护,包括添加新用户、删除用户、编辑用户、根据姓名/部门查询用户。用户可以进入部门管理模块,管理旅社的部门数据,如下图所示。 同理用户可以进入到菜单管理模块,对系统的菜单进行管理,菜单管理模块的操作界面如下图所示。 民宿档案模块第二个模块是民宿档案模块,民宿档案就是用来管理民宿的数据,民宿档案包括民宿的名称、面积、房号、房间类型、早餐情况、价格、备注等,以下是民宿档案模块的主界面。用户可以点击顶部的“新增”按钮,进入民宿档案添加界面,添加民宿档案数据,如下图所示。 其中房间类型为下拉框单项选择,如下图所示。还有早餐情况也是下拉单选,如下图所示。 用户可以对现有的民宿档案数据进行编辑更新,只需点击每一行民宿档案数据的“编辑”按钮,即可进入民宿档案数据的编辑界面,如下图所示。 用户也可以对不需要的民宿数据进行删除操作,用户点击删除时,系统会弹出二次确认弹框,如下图所示。  民宿新闻模块第三个模块是民宿新闻模块,民宿新闻就是用来管理民宿的新闻资讯,包含的功能如下所示。 民宿新闻包括民宿的名称、面积、房号、房间类型、早餐情况、价格、备注等,以下是民宿新闻模块的主界面,其中的图片仅供测试样例使用。用户可以点击顶部的“新增”按钮,进入民宿新闻添加界面,添加民宿新闻数据,如下图所示。 新闻描述字段采用了 ueditor 富文本编辑器,这是由百度 web 前端研发部开发的所见即所得的开源富文本编辑器,具有轻量、可定制、用户体验优秀等特点,基于 MIT 开源协议,所有源代码可自由修改和使用。 用户可以对现有的民宿新闻数据进行编辑更新,只需点击每一行民宿新闻数据的“编辑”按钮,即可进入民宿新闻数据的编辑界面,如下图所示。 民宿预定模块第四个模块是民宿预定模块,旅客可以在民宿预定模块中预定民宿,达到旅客的住宿目的,民宿预定模块包含的功能如下所示。民宿预定包括了预定民宿 ID、预定民宿名称、预定日期、下单时间、下单人 ID、下单人姓名、价格、是否付款、下单备注等字段,旅客首先进入民宿档案模块,可以看到每一行民宿数据都有一个预约按钮,如下图所示。 如用户点击 1 幢 102 民宿的预约按钮后,会弹出预约确认框,需要输入预约的日期,日期表单默认选择今日,如下图所示。 旅客需要点击“确认预约”按钮,完成预约操作,系统给与“预约成功”提示,如下图所示。 预约成功后,旅客可以从民宿预定模块中进行查询,如下图所示。 最后旅客进行付款操作,点击每一行右侧的付款按钮,如下图所示。支付完成后,系统将预定单的支付状态改为付款,预定流程结束,如下图所示。 民宿评论模块 第五个模块是民宿预定模块,旅客可以在民宿预定结束后评论民宿,以帮助更多的人了解民宿,民宿评论模块包含的功能如下所示。 民宿评论包括了民宿名称、民宿 ID、评论时间、评论内容、评论人 ID、评论人姓名等字段,旅客首先进入民宿档案模块,可以看到每一行民宿数据都有一个评论按钮,如下图所示。 旅客点击评论后,系统给与弹框反馈,如下图所示。  用户输入评论内容后,点击确认评论按钮,即可完成评论操作,如下图所示。  旅客评论后,即可在民宿评论模块中查看此评论数据,如下图所示。 也可以在民宿模块中,双击民宿数据查看评论信息,如下图所示。 项目总结本软件是基于 VueSpringBoot 的假日旅社管理系统,包含了民宿档案、民宿新闻、民宿预定、民宿评论这四个功能模块。 开发本系统的目的,就是为了帮助旅游景点的民宿企业提高民宿管理效率,降低人力成本,让旅游景点的民宿企业获得更多的经济效益。
好的,我会根据您的要求,为您提供一个基于SpringBootVue的图书管理系统的概要设计。 1. 后端技术栈 - Spring Boot:用于构建Web应用程序的框架,提供了许多自动配置和开箱即用的功能。 - Spring MVC:用于处理Web请求和响应的框架。 - Spring Data JPA:用于处理与数据库的交互的框架。 - MySQL:用于存储数据的关系型数据库。 2. 前端技术栈 - Vue:用于构建用户界面的框架,提供了许多简洁、灵活和易于使用的功能。 - ElementUI:基于Vue的组件库,提供了许多高质量的UI组件。 - Axios:用于处理与后端的HTTP请求的框架。 3. 功能列表 - 用户登录、注册、退出登录。 - 图书的新增、修改、删除、查询、借阅、还书等操作。 - 图书分类的新增、修改、删除、查询等操作。 - 用户的个人信息管理、密码修改等操作。 - 图书借阅记录的查询等操作。 4. 技术架构 - 前端代码放置于src/main/resources/static目录下,使用Vue进行开发。 - 前端与后端的交互使用Axios进行HTTP请求。 - 后端代码放置于src/main/java目录下,使用Spring Boot进行开发。 - 后端提供RESTful API接口,用于前端与后端的交互。 - 后端使用Spring Data JPA进行与MySQL的交互,实现数据持久化。 5. 数据库设计 - 图书表:id、book_name、author、publisher、price、stock、category_id - 图书分类表:id、category_name - 用户表:id、username、password、email、phone、role - 图书借阅记录表:id、user_id、book_id、borrow_time、return_time 以上是我为您提供的基于SpringBootVue的图书管理系统的概要设计,您可以根据这个框架进行开发和设计,具体实现还需要根据实际需求进行调整和完善。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值