SpringBoot+Vue实现简单的登录注册功能
作者:mmseoamin日期:2023-12-18

文章目录

  • 一、前言
    • 1.开发环境
    • 2.功能
    • 3.项目运行截图
    • 二、撸代码
      • 1.构建前端项目
      • 2.构建后端项目
      • 3.前端页面编写
      • 4.后端代码编写
      • 5.前后端联调
      • 三、小结

        一、前言

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

        项目下载:

        前后端登录注册系统源码下载:

        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.项目运行截图

        SpringBoot+Vue实现简单的登录注册功能,在这里插入图片描述,第1张

        SpringBoot+Vue实现简单的登录注册功能,在这里插入图片描述,第2张

        SpringBoot+Vue实现简单的登录注册功能,在这里插入图片描述,第3张

        二、撸代码

        1.构建前端项目

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

        vue create loginandregister-vue
        

        然后选择图中的这个选项,表示自定义创建项目

        SpringBoot+Vue实现简单的登录注册功能,在这里插入图片描述,第4张

        再按图中的选择就行,空格是选中,然后回车进入下一步

        SpringBoot+Vue实现简单的登录注册功能,在这里插入图片描述,第5张

        选择vue2.x的版本,因为我从vue2开始学的,vue3的一些新特性,配置还不懂(流下无知的泪水)

        SpringBoot+Vue实现简单的登录注册功能,在这里插入图片描述,第6张

        这里输入n,使用vue默认的路由,因为vue有两种路由模式,hash和history,这里就不深入了😶

        SpringBoot+Vue实现简单的登录注册功能,在这里插入图片描述,第7张

        然后就一直选第一个吧,毕竟创工程好像没啥好讲的(其实就是懒,不想敲了😝),最后一个选项输入n,意思是是否将此作为未来项目的预设(是/否) 我这里选择n了

        SpringBoot+Vue实现简单的登录注册功能,在这里插入图片描述,第8张

        这杨紫就说明创建成功了,如果创建的很慢,或者出错,可以看看我都这篇文章,我是用这个办法解决的。解决创建vue项目太慢问题

        SpringBoot+Vue实现简单的登录注册功能,在这里插入图片描述,第9张

        2.构建后端项目

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

         
              
                  org.springframework.boot
                  spring-boot-starter-web
              
              
                  org.projectlombok
                  lombok
                  true
              
              
                  mysql
                  mysql-connector-java
                  8.0.30
              
              
                  com.baomidou
                  mybatis-plus-boot-starter
                  3.5.2
              
              
                  org.apache.httpcomponents
                  httpcore
                  4.4.12
              
              
                  com.alibaba
                  fastjson
                  1.2.83
              
              
                  org.springframework.boot
                  spring-boot-starter-test
                  test
              
          
        

        到此后端工程就创建完了,不过我们还可以生成后端的代码,省的我们掉头发了,只要修改指定的配置就会生成controller,service,mapper,model。生成好后,把文件复制到后端工程里。这样我们就写完了一半的代码了。

        创建数据库,导入user.sql文件

        SpringBoot+Vue实现简单的登录注册功能,在这里插入图片描述,第10张

        然后打开代码生成器工程,里面就一个Generator类,修改我加了TODO注释的地方,运行成功会跳出生成好的文件夹,然后无脑cv到我们刚才创建好的后端工程里,这样我们的后端工程的基本结构就都有了。

        import com.baomidou.mybatisplus.annotation.DbType;
        import com.baomidou.mybatisplus.annotation.FieldFill;
        import com.baomidou.mybatisplus.generator.AutoGenerator;
        import com.baomidou.mybatisplus.generator.config.*;
        import com.baomidou.mybatisplus.generator.config.po.TableFill;
        import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
        import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
        import java.awt.*;
        import java.io.File;
        import java.io.IOException;
        import java.util.Arrays;
        /**
         * MyBatis-Plus 代码生成类
         */
        public class Generator {
        	// TODO 修改服务名   数据表名   包名
        	private static final String SERVICE_NAME = "lgy";
        	private static final String PACK_NAME = "com.wusuowei";
        	//TODO 修改数据库账号
        	private static final String DATA_SOURCE_USER_NAME  = "root";
        	//TODO 修改数据库密码
        	private static final String DATA_SOURCE_PASSWORD  = "mysql";
        	//TODO 修改数据库连接
        	private static final String DATA_URL = "jdbc:mysql://127.0.0.1:3306/springboot-vue?serverTimezone=UTC&useUnicode=true&useSSL=false&characterEncoding=utf8";
        	//TODO 修改要生成的表
        	private static final String[] TABLE_NAMES = new String[]{
        			"user"
        	};
        	// TODO 默认生成entity,需要生成DTO修改此变量
        	// 一般情况下要先生成 DTO类 然后修改此参数再生成 PO 类。
        	private static final Boolean IS_DTO = false;
        	public static void main(String[] args) throws IOException {
        		// 代码生成器
        		AutoGenerator mpg = new AutoGenerator();
        		// 选择 freemarker 引擎,默认 Velocity
        		mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        		// 全局配置
        		GlobalConfig gc = new GlobalConfig();
        		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 = new DataSourceConfig();
        		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 = new PackageConfig();
        		pc.setModuleName(SERVICE_NAME);
        		pc.setParent(PACK_NAME);
        		pc.setServiceImpl("service.impl");
        		pc.setXml("mapper");
        		pc.setEntity("model.po");
        		mpg.setPackageInfo(pc);
        		// 设置模板
        		TemplateConfig tc = new TemplateConfig();
        		mpg.setTemplate(tc);
        		// 策略配置
        		StrategyConfig strategy = new StrategyConfig();
        		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(
        				new TableFill("create_date", FieldFill.INSERT),
        				new TableFill("change_date", FieldFill.INSERT_UPDATE),
        				new TableFill("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(new File(path));
        	}
        }
        

        3.前端页面编写

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

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

        下载完后在main.js入口文件中导入,注册第三方库

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

        编写登录页Login.vue

        
        
        

        注册页面views/Register.vue

        
        
        

        首页views/Index.vue,就是单纯为了演示功能

        
        
        

        页面写完了就是配置路由规则了,修改router/index.js

        import Vue from 'vue'
        import VueRouter from 'vue-router'
        import Login from '../views/Login.vue'
        import Register from '../views/Register.vue'
        import Index 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 = new VueRouter({
          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)定义统一返回结果工具类,这样前端方便取出后端传来的数据

        import com.alibaba.fastjson.JSON;
        import com.alibaba.fastjson.TypeReference;
        import org.apache.http.HttpStatus;
        import java.util.HashMap;
        import java.util.Map;
        /**
         * 返回数据
         *
         * @author Mark sunlightcs@gmail.com
         */
        public class R extends HashMap {
            private static final long serialVersionUID = 1L;
            public R setData(Object data) {
                put("data",data);
                return this;
            }
            //利用fastjson进行反序列化
            public  T getData(TypeReference typeReference) {
                Object data = get("data");	//默认是map
                String jsonString = JSON.toJSONString(data);
                T t = JSON.parseObject(jsonString, typeReference);
                return t;
            }
            public R() {
                put("code", 20000);
                put("msg", "success");
            }
            public static R error() {
                return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");
            }
            public static R error(String msg) {
                return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
            }
            public static R error(int code, String msg) {
                R r = new R();
                r.put("code", code);
                r.put("msg", msg);
                return r;
            }
            public static R ok(String msg) {
                R r = new R();
                r.put("msg", msg);
                return r;
            }
            public static R ok(Map map) {
                R r = new R();
                r.putAll(map);
                return r;
            }
            public static R ok() {
                return new R();
            }
            public R put(String key, Object value) {
                super.put(key, value);
                return this;
            }
            public  Integer getCode() {
                return (Integer) this.get("code");
            }
        }
        

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

        public interface UserService extends IService {
            User getByNameAndPassword(String name,String password);
            User getByName(String name);
            void addUser(User user);
        }
        
        @Slf4j
        @Service
        public class UserServiceImpl extends ServiceImpl implements UserService {
            @Autowired
            UserMapper userMapper;
            @Override
            public User getByNameAndPassword(String name,String password) {
                LambdaQueryWrapper wrapper = new LambdaQueryWrapper();
                wrapper.eq(User::getPassword,password);
                wrapper.eq(User::getUsername, name);
                return userMapper.selectOne(wrapper);
            }
            @Override
            public User getByName(String name) {
                LambdaQueryWrapper wrapper = new LambdaQueryWrapper();
                wrapper.eq(User::getUsername, name);
                return userMapper.selectOne(wrapper);
            }
            @Override
            public void addUser(User user) {
                userMapper.insert(user);
            }
        }
        
        @Slf4j
        @RestController
        public class UserController {
            @Autowired
            private UserService  userService;
            @PostMapping("/login")
            public R login(@RequestBody User user){
                String name = user.getUsername();
                String password = user.getPassword();
                User userDB = userService.getByNameAndPassword(name,password);
                if(userDB==null){
                    return R.error(20001,"没有该用户");
                }
                return R.ok("登录成功").setData(userDB);
            }
            @PostMapping("/register")
            public R regiseter(@RequestBody User user){
                String name = user.getUsername();
                User checkName = userService.getByName(name);
                if(checkName!=null){
                    return R.error(20001,"用户名已被注册");
                }
                userService.addUser(user);
                return R.ok("注册成功").setData(user);
            }
        }
        

        4)在启动类上加上@MapperScan("com.wusuowei.lgy.mapper")注解,扫描每个Mapper接口,生成相应的实现类

        5.前后端联调

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

        SpringBoot+Vue实现简单的登录注册功能,在这里插入图片描述,第11张

        在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实现完善的登录注册功能

        三、小结

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