0


SpringBoot+Vue实现简单的登录注册功能

文章目录

一、前言

😶‍🌫️😶‍🌫️😶‍🌫️如果你是一名全干程序员,那前后端跨域问题一定是家常便饭,作者今天带大家写一个最简单的前后端分离登录系统,方便我们理解前后端分离项目的跨域以及数据传输问题。因为要照顾小白,所以我会写的详细一点,不足的地方,大家多多指点,交流啦😉😉😉

项目下载:
前后端登录注册系统源码下载:
gitee:https://gitee.com/wusupweilgy/springboot-vue.git
蓝奏云:https://wwp.lanzoup.com/iYWSU0r6bf7c

代码生成器下载:
gitee:https://gitee.com/wusupweilgy/wusuowei-plus-generator.git
蓝奏云:https://wwp.lanzoup.com/iGIJL0rbvorg

1.开发环境

jdk8+mysql8+vue2+mybatis-plus+springboot

2.功能

1.简单的注册、登录功能。

3.项目运行截图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、撸代码

1.构建前端项目

这里就默认大家都安装过node.js环境了,我们需要使用npm的vue cli创建vue2的工程,这里我就用原始一点的方法创建前端工程,你也可以使用开发工具创建,都差不多。输入vue create 项目名,这里注意项目名只能是小写

vue create loginandregister-vue

然后选择图中的这个选项,表示自定义创建项目
在这里插入图片描述
再按图中的选择就行,空格是选中,然后回车进入下一步
在这里插入图片描述
选择vue2.x的版本,因为我从vue2开始学的,vue3的一些新特性,配置还不懂(流下无知的泪水)
在这里插入图片描述
这里输入n,使用vue默认的路由,因为vue有两种路由模式,hash和history,这里就不深入了😶
在这里插入图片描述
然后就一直选第一个吧,毕竟创工程好像没啥好讲的(其实就是懒,不想敲了😝),最后一个选项输入n,意思是是否将此作为未来项目的预设(是/否) 我这里选择n了
在这里插入图片描述
这杨紫就说明创建成功了,如果创建的很慢,或者出错,可以看看我都这篇文章,我是用这个办法解决的。解决创建vue项目太慢问题
在这里插入图片描述

2.构建后端项目

后端就是使用idea创建springboot工程了,这里展示下项目依赖,你导入就好了

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.30</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.2</version></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpcore</artifactId><version>4.4.12</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.83</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>

到此后端工程就创建完了,不过我们还可以生成后端的代码,省的我们掉头发了,只要修改指定的配置就会生成controller,service,mapper,model。生成好后,把文件复制到后端工程里。这样我们就写完了一半的代码了。
创建数据库,导入user.sql文件
在这里插入图片描述
然后打开代码生成器工程,里面就一个Generator类,修改我加了TODO注释的地方,运行成功会跳出生成好的文件夹,然后无脑cv到我们刚才创建好的后端工程里,这样我们的后端工程的基本结构就都有了。

importcom.baomidou.mybatisplus.annotation.DbType;importcom.baomidou.mybatisplus.annotation.FieldFill;importcom.baomidou.mybatisplus.generator.AutoGenerator;importcom.baomidou.mybatisplus.generator.config.*;importcom.baomidou.mybatisplus.generator.config.po.TableFill;importcom.baomidou.mybatisplus.generator.config.rules.NamingStrategy;importcom.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;importjava.awt.*;importjava.io.File;importjava.io.IOException;importjava.util.Arrays;/**
 * MyBatis-Plus 代码生成类
 */publicclassGenerator{// TODO 修改服务名   数据表名   包名privatestaticfinalString SERVICE_NAME ="lgy";privatestaticfinalString PACK_NAME ="com.wusuowei";//TODO 修改数据库账号privatestaticfinalString DATA_SOURCE_USER_NAME  ="root";//TODO 修改数据库密码privatestaticfinalString DATA_SOURCE_PASSWORD  ="mysql";//TODO 修改数据库连接privatestaticfinalString DATA_URL ="jdbc:mysql://127.0.0.1:3306/springboot-vue?serverTimezone=UTC&useUnicode=true&useSSL=false&characterEncoding=utf8";//TODO 修改要生成的表privatestaticfinalString[] TABLE_NAMES =newString[]{"user"};// TODO 默认生成entity,需要生成DTO修改此变量// 一般情况下要先生成 DTO类 然后修改此参数再生成 PO 类。privatestaticfinalBoolean IS_DTO =false;publicstaticvoidmain(String[] args)throwsIOException{// 代码生成器AutoGenerator mpg =newAutoGenerator();// 选择 freemarker 引擎,默认 Velocity
        mpg.setTemplateEngine(newFreemarkerTemplateEngine());// 全局配置GlobalConfig gc =newGlobalConfig();
        gc.setFileOverride(true);//生成路径String path =System.getProperty("user.dir")+"/src/main/java";
        gc.setOutputDir(path);//TODO 修改作者名
        gc.setAuthor("lgy");
        gc.setOpen(false);
        gc.setSwagger2(false);
        gc.setServiceName("%sService");
        gc.setBaseResultMap(true);
        gc.setBaseColumnList(true);if(IS_DTO){
            gc.setSwagger2(true);
            gc.setEntityName("%sDTO");}
        mpg.setGlobalConfig(gc);// 数据库配置DataSourceConfig dsc =newDataSourceConfig();
        dsc.setDbType(DbType.MYSQL);
        dsc.setUrl(DATA_URL);//        dsc.setDriverName("com.mysql.jdbc.Driver");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername(DATA_SOURCE_USER_NAME);
        dsc.setPassword(DATA_SOURCE_PASSWORD);
        mpg.setDataSource(dsc);// 包配置PackageConfig pc =newPackageConfig();
        pc.setModuleName(SERVICE_NAME);
        pc.setParent(PACK_NAME);

        pc.setServiceImpl("service.impl");
        pc.setXml("mapper");
        pc.setEntity("model.po");
        mpg.setPackageInfo(pc);// 设置模板TemplateConfig tc =newTemplateConfig();
        mpg.setTemplate(tc);// 策略配置StrategyConfig strategy =newStrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);
        strategy.setInclude(TABLE_NAMES);
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setTablePrefix(pc.getModuleName()+"_");// Boolean类型字段是否移除is前缀处理
        strategy.setEntityBooleanColumnRemoveIsPrefix(true);
        strategy.setRestControllerStyle(true);// 自动填充字段配置
        strategy.setTableFillList(Arrays.asList(newTableFill("create_date",FieldFill.INSERT),newTableFill("change_date",FieldFill.INSERT_UPDATE),newTableFill("modify_date",FieldFill.UPDATE)));
        mpg.setStrategy(strategy);

        mpg.execute();String packname = PACK_NAME;
        packname = packname.replace(".","/");
        path = path+"/"+packname+"/"+SERVICE_NAME;System.err.println(path);Desktop.getDesktop().open(newFile(path));}}

3.前端页面编写

使用webstrom打开前端工程,下载element-ui库,axios库

npm i element-ui -S
npm i axios -S

下载完后在

main.js

入口文件中导入,注册第三方库

importVue from 'vue'importApp from './App.vue'
importrouter from './router'
importstore from './store'
importElementUI from 'element-ui';importaxios from 'axios';import 'element-ui/lib/theme-chalk/index.css';Vue.config.productionTip =falseVue.prototype.$axios = axios
axios.defaults.baseURL = 'http://localhost:8088';//后端地址//注册插件Vue.use(ElementUI)newVue({
  router,
  store,
  render: h =>h(App)}).$mount('#app')

编写登录页

Login.vue
<template><div><el-form ref="loginForm":model="form":rules="rules" label width=" 80px"class="login-box"><h3 class="login-title">欢迎登录</h3><el-form-item label="账号" prop="username"><el-input type="text" placeholder=" 请输入账号" v-model="form.username"/></el-form-item><el-form-item label="密码" prop="password"><el-input type="password" placeholder=" 请输入密码" v-model=" form.password"/></el-form-item><el-form-item><el-button type="primary" v-on:click="onSubmit('loginForm')">登录</el-button><el-button type="primary" v-on:click="$router.push('/register')">注册</el-button></el-form-item></el-form><el-dialog
                title="温馨提示":visible.sync="dialogVisible"
                width="30%":before-close="handleClose"><span>请输入账号和密码</span><span slot="footer"class="dialog-footer"><el-button type="primary"@click="dialogVisible = false">确 定</el-button></span></el-dialog></div></template><script>
    export default{
        name:"Login",data(){return{

                form:{
                    username: '',
                    password: ''
                },// 表单验证, 需要在el-form-item- 元素中增加prop属性
                rules:{
                    username:[{required:true, message:'账号不可为空', trigger:'blur'}],
                    password:[{required:true, message:'密码不可为空', trigger:'blur'}]},//对话框显示和隐藏
                dialogVisible:false}},
        methods:{
            handleClose: function (){
                console.log("Handle Close,空函数");},onSubmit(formName){//为表单绑定验证功能this.$refs [formName].validate((valid)=>{if(valid){this.$axios.post('/login',{
                            username:this.form.username,
                            password:this.form.password
                        }).then(response =>{if(response.data.code===20000){//使用vue-router 路由到指定页面,该方式称之为编程式导航this.$router.push({
                                        path:"/index",
                                        query:{username:response.data.data.username}});
                                    console.log(response.data);this.$message.success(response.data.msg)}else{
                                    console.log(response.data);this.$message.error(this.form.username+response.data.msg)}})}else{this.dialogVisible =true;returnfalse;}});},}}</script><style scoped>.login-box {
    border:1px solid #DCDFE6;
    width:350px;
    margin:50px auto;
    padding:35px 35px 15px 35px;
    border-radius:5px;-webkit-border-radius:5px;-moz-border-radius:5px;
    box-shadow:0025px #909399;}.login-title {
    text-align: center;
    margin:0 auto 40px auto;
    color: #303133;}</style>

注册页面

views/Register.vue
<template><div><el-form ref="loginForm":model="form":rules="rules" label width=" 80px"class="login-box"><h3 class="login-title">欢迎登录</h3><el-form-item label="账号" prop="username"><el-input type="text" placeholder=" 请输入账号" v-model="form.username"/></el-form-item><el-form-item label="密码" prop="password"><el-input type="password" placeholder=" 请输入密码" v-model=" form.password"/></el-form-item><el-form-item label="确认密码" prop="checkPass"><el-input type="password" placeholder=" 请确认密码" v-model="form.checkPass"/></el-form-item><el-form-item><el-button type="primary" v-on:click="onSubmit('loginForm')">注册</el-button></el-form-item></el-form><el-dialog
                title="温馨提示":visible.sync="dialogVisible"
                width="30%":before-close="handleClose"><span>请输入账号和密码</span><span slot="footer"class="dialog-footer"><el-button type="primary"@click="dialogVisible = false">确 定</el-button></span></el-dialog></div></template><script>
    export default{
        name:"Login",data(){var validatePass2 =(rule, value, callback)=>{if(value === ''){callback(newError('请再次输入密码'));}elseif(value !==this.form.password){callback(newError('两次输入密码不一致!'));}else{callback();}};return{
                form:{
                    username: '',
                    password: '',
                    checkPass: '',},// 表单验证, 需要在el-form-item- 元素中增加prop属性
                rules:{
                    checkPass:[{validator: validatePass2, trigger:'blur'}],
                    username:[{required:true, message:'账号不可为空', trigger:'blur'}],
                    password:[{required:true, message:'密码不可为空', trigger:'blur'}]},//对话框显示和隐藏
                dialogVisible:false}},
        methods:{
            handleClose: function (){
                console.log("Handle Close,空函数");},onSubmit(formName){//为表单绑定验证功能this.$refs [formName].validate((valid)=>{if(valid){this.$axios.post('/register',{
                            username:this.form.username,
                            password:this.form.password
                        }).then(response =>{if(response.data.code===20000){//使用vue-router 路由到指定页面,该方式称之为编程式导航this.$router.push("/login");this.$message.success(response.data.msg)}else{
                                    console.log(response.data);this.$message.error(this.form.username+"已被注册")}})}else{this.dialogVisible =true;returnfalse;}});},},created(){
            console.log(this)}}</script><style scoped>.login-box {
        border:1px solid #DCDFE6;
        width:350px;
        margin:50px auto;
        padding:35px 35px 15px 35px;
        border-radius:5px;-webkit-border-radius:5px;-moz-border-radius:5px;
        box-shadow:0025px #909399;}.login-title {
        text-align: center;
        margin:0 auto 40px auto;
        color: #303133;}</style>

首页

views/Index.vue

,就是单纯为了演示功能

<template><div><h1>欢迎{{$route.query.username}}来到首页</h1></div></template><script></script><style scoped></style>

页面写完了就是配置路由规则了,修改

router/index.js
importVue from 'vue'importVueRouter from 'vue-router'
importLogin from '../views/Login.vue'
importRegister from '../views/Register.vue'
importIndex from '../views/Index.vue'

Vue.use(VueRouter)const routes =[{
    path:'/login',
    name:'Login',
    component:Login},{
    path: '/register',
    name: 'Register',
    component:Register},{
    path:'/index',
    name:'Index',
    component:Index},]const router =newVueRouter({
  routes
})
export default router

这时你就可以运行项目了,不过肯定会报错,这是因为eslint校验,需要在

vue.config.js

中加入

lintOnSave:false

,到这前端代码就差不多写完了,不过还有坑,不知道你们发现了没,没发现的话,那就等前后端联调的时候再说吧

4.后端代码编写

1)创建

application.yml

配置文件,配置数据库连接。

server:
  port:8088
spring:
  application:
    name: content-api
  datasource:
    driver-class-name:com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springboot-vue?serverTimezone=UTC&userUnicode=true&useSSL=false
    username: root
    password: mysql
mybatis-plus:
  configuration:
    log-impl:org.apache.ibatis.logging.stdout.StdOutImpl

2)定义统一返回结果工具类,这样前端方便取出后端传来的数据

importcom.alibaba.fastjson.JSON;importcom.alibaba.fastjson.TypeReference;importorg.apache.http.HttpStatus;importjava.util.HashMap;importjava.util.Map;/**
 * 返回数据
 *
 * @author Mark [email protected]
 */publicclassRextendsHashMap<String,Object>{privatestaticfinallong serialVersionUID =1L;publicRsetData(Object data){put("data",data);returnthis;}//利用fastjson进行反序列化public<T>TgetData(TypeReference<T> typeReference){Object data =get("data");//默认是mapString jsonString = JSON.toJSONString(data);T t = JSON.parseObject(jsonString, typeReference);return t;}publicR(){put("code",20000);put("msg","success");}publicstaticRerror(){returnerror(HttpStatus.SC_INTERNAL_SERVER_ERROR,"未知异常,请联系管理员");}publicstaticRerror(String msg){returnerror(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);}publicstaticRerror(int code,String msg){R r =newR();
        r.put("code", code);
        r.put("msg", msg);return r;}publicstaticRok(String msg){R r =newR();
        r.put("msg", msg);return r;}publicstaticRok(Map<String,Object> map){R r =newR();
        r.putAll(map);return r;}publicstaticRok(){returnnewR();}publicRput(String key,Object value){super.put(key, value);returnthis;}publicIntegergetCode(){return(Integer)this.get("code");}}

3)接口编写(分别是UserService,UserServiceImpl,UserController)

publicinterfaceUserServiceextendsIService<User>{UsergetByNameAndPassword(String name,String password);UsergetByName(String name);voidaddUser(User user);}
@Slf4j@ServicepublicclassUserServiceImplextendsServiceImpl<UserMapper,User>implementsUserService{@AutowiredUserMapper userMapper;@OverridepublicUsergetByNameAndPassword(String name,String password){LambdaQueryWrapper<User> wrapper =newLambdaQueryWrapper<User>();
        wrapper.eq(User::getPassword,password);
        wrapper.eq(User::getUsername, name);return userMapper.selectOne(wrapper);}@OverridepublicUsergetByName(String name){LambdaQueryWrapper<User> wrapper =newLambdaQueryWrapper<User>();
        wrapper.eq(User::getUsername, name);return userMapper.selectOne(wrapper);}@OverridepublicvoidaddUser(User user){
        userMapper.insert(user);}}
@Slf4j@RestControllerpublicclassUserController{@AutowiredprivateUserService  userService;@PostMapping("/login")publicRlogin(@RequestBodyUser user){String name = user.getUsername();String password = user.getPassword();User userDB = userService.getByNameAndPassword(name,password);if(userDB==null){returnR.error(20001,"没有该用户");}returnR.ok("登录成功").setData(userDB);}@PostMapping("/register")publicRregiseter(@RequestBodyUser user){String name = user.getUsername();User checkName = userService.getByName(name);if(checkName!=null){returnR.error(20001,"用户名已被注册");}
        userService.addUser(user);returnR.ok("注册成功").setData(user);}}

4)在启动类上加上

@MapperScan("com.wusuowei.lgy.mapper")

注解,扫描每个Mapper接口,生成相应的实现类

5.前后端联调

运行前后端项目,进行注册,发现报错,这是因为浏览器的同源策略,前端给后端发请求时,不能进行跨域访问,这里需要我们进行跨域配置
在这里插入图片描述

main.js

中修改

axios.defaults.baseURL ='/api';//后端地址

vue.config.js

中添加

  devServer:{// 本地配置
    proxy:{'/api':{
        target:"http://localhost:8088",//实际访问的ip
        changeOrigin:true,
        pathRewrite:{'^/api':""//实际访问的ip}},}}

重启前端项目,这时就可以跨域了,功能都正常了
这里只是实现了基本登录注册功能,其实还有很多逻辑上的问题,比如可以跳过登录,直接访问首页,如果要实现完善的登录注册工程,可以看下一篇进阶文章,我会在本工程的基础上进行改进。
下一篇:SpringBoot+Vue集成JWT实现完善的登录注册功能

三、小结

😶😶😶这个项目的目的时为了帮助大家理解前后端的跨域以及数据如何传输,如果这篇文章有幸帮助到你,希望读者大大们可以给作者点个赞,创作不易,如果有对后端技术、前端领域感兴趣的,可以关注作者,互相交流学习😶‍🌫️😶‍🌫️😶‍🌫️

标签: vue.js spring boot java

本文转载自: https://blog.csdn.net/weixin_51603038/article/details/129424609
版权归原作者 无所谓^_^ 所有, 如有侵权,请联系我们删除。

“SpringBoot+Vue实现简单的登录注册功能”的评论:

还没有评论