ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Spring Boot+Vue房屋租赁系统:前后端分离毕设项目完整解析

Spring Boot+Vue房屋租赁系统:前后端分离毕设项目完整解析 做毕设或者自己练手的时候最怕遇到什么不是代码有多难写而是下了个所谓的“完整项目”结果源码缺胳膊少腿、数据库脚本跑不通、文档跟代码对不上折腾一晚上连登录页都出不来。我今天要聊的这个小型房屋租赁系统是基于 Spring Boot Vue 前后端分离的完整项目包含源码、数据库脚本和配套文档定位很明确——让一个计算机相关专业的学生或者刚入行的开发者拿到手就能看懂架构、跑通流程、改成自己的东西。这个小系统解决的问题非常接地气房东手里有多套房源登记信息、带人看房、签合同、算水电全靠本子和脑子租客想看房得挨个打电话问房子租出去之后账单和报修又陷入混乱。把这些线下流程搬到线上做成三个角色都能用的管理系统就是这套项目存在的意义。适合用来做毕业设计、课程设计也适合想系统学习 Spring Boot Vue 前后端分离项目从零搭建过程的人。我花了一下午从拉代码到完整跑通把整个过程、核心设计思路和踩过的坑整理在下面照着做基本能复现。1. 项目全景拆解业务需求与技术选型思路1.1 这个系统到底要解决什么问题房屋租赁这个领域业务模型看着简单真正拆开却很琐碎。传统线下管理有几个绕不开的痛点第一房源信息不透明。房东有多少套房、每套是什么状态、租给谁、什么时候到期全靠台账管理。房源一多信息更新滞后是常态房子明明空着房东自己都搞不清。第二租赁流程没有闭环。从租客看房、谈价格、签合同、付押金到后续交水电费、报修每个环节都是独立的线下动作一旦中间出差错责任很难追溯。第三账单计算容易扯皮。房租、水费、电费、物业费不同房源收费标准还不一样人工算账漏记、错记都难免。这套系统的核心业务就是围绕这三件事展开房源管理发布、上下架、状态维护、租赁管理预约看房、合同签约、退租、账单管理生成账单、缴费记录、欠费提醒。外加辅助功能报修工单、公告通知、个人信息维护。从业务量级来看这属于典型的小型管理系统不需要复杂的分布式架构单机部署完全够用。目标用户是房东个人或小规模中介公司数据量在几百套房、几千个租客这个量级。1.2 为什么选 Spring Boot Vue 做前后端分离现在的 JavaWeb 项目除非有特殊的渲染需求基本不会再考虑 JSP 或者 Thymeleaf 那种服务端渲染方案了。这套项目选 Spring Boot Vue 是当前最主流的小型管理系统搭配原因很实在后端用 Spring Boot最大的价值在于“约定大于配置”。一个启动类加几个注解内嵌 Tomcat打完包直接 java -jar 就能跑省掉部署 Web 容器这一整套繁琐流程。配合 MyBatis Plus单表 CRUD 基本不用写 SQL开发效率提升非常明显。对于一个小型租赁系统Spring Boot 提供的自动配置能力能让开发者在三天内把后端骨架全部搭完把精力集中在业务逻辑上。前端用 Vue组件化开发让页面维护变得非常清晰。配合 Element UI 组件库表格、表单、弹窗、分页这些管理后台的常见元素都能直接调用不用从零写样式。而且 Vue 的学习曲线在前端框架里相对平缓对以 Java 为主的学生项目来说属于容易上手的选择。前后端分离架构还有一个隐性的好处分工明确、接口先行。后端只负责提供 JSON 数据接口前端只负责渲染和交互两边通过约定的接口文档联调。这在毕设答辩里也是一个很好的亮点——可以说明你理解了 Courser 架构而不是把代码糊在一个包里这在项目答辩里是一个很实用的加分项。1.3 小型系统也要有的工程化意识这套项目虽然在业务上“小”但工程结构上并没有偷工减料。后端分 controller、service、mapper、entity、config、utils 几层前端分 views、router、api、utils 几个目录。这种分层设计不是多余的——它让代码的组织方式跟着职责走新增功能时能明确知道该改哪个文件。数据库脚本提供完整的建表语句和初始数据包含测试账号。文档部分则把项目介绍、技术说明、运行步骤、功能清单打包在一起。对一个拿来学习和演示的项目来说这套配套算是比较齐全了。另外要强调一个点很多人觉得小型系统不需要做权限控制这个观念要改。哪怕是个人用的管理后台不同角色能看到的菜单和能操作的按钮也应该有区分。这套系统的设计思路是用户角色分为管理员、房东、租客三种租客只能浏览房源、发起预约、查看自己的合同和账单房东能管理自己的房源和处理预约管理员拥有全部权限。这种基于角色的访问控制在实现上并不复杂但对系统的完整度提升非常大。2. 核心方案设计与功能拆解2.1 用户角色与权限体系设计刚才提到系统分三种角色这里展开说一下设计方案。数据库层面只在用户表里加一个 role 字段用数字区分0 管理员、1 房东、2 租客。登录成功后后端返回用户的角色信息前端根据角色动态生成菜单。后端通过拦截器校验接口访问权限。比如发布房源和修改房源状态的接口只允许房东和管理员角色访问提交预约和查看个人账单的接口只允许租客访问。具体做法是写一个拦截器在 preHandle 方法里从请求头取出令牌解析出用户 ID 和角色然后通过反射或者手动判断当前请求的接口路径是否在该角色允许的列表内。这套方案的优点是简单直接适合小型系统缺点是权限粒度过粗精确到按钮级别的控制还需要前端配合路由守卫完成。但在租赁场景里这种级别的权限控制已经足够。2.2 核心业务模块划分与数据流转整个系统的业务模块可以拆成六大块房源管理发布房源填写地址、户型、面积、租金、押金、图片、编辑房源、上下架房源、房源状态自动更新待租/已租/停租。预约看房租客在房源详情页发起预约选择时间房东在后台查看预约列表确认或拒绝。租赁合同管理预约通过后租客可在线签署租房合同合同包含租期、租金、押金、支付方式等关键信息。账单管理根据合同自动生成每月账单包含房租、水费、电费租客在线缴费房东查看账单明细和收款记录。报修管理租客提交报修工单填写问题类型和描述房东或管理员处理并更新进度。公告管理管理员发布系统公告所有用户均可查看。数据流转的路径很清晰租客查看房源 - 发起预约 - 房东确认 - 租客签合同 - 系统生成账单 - 租客缴费 - 合同到期/退租 - 房源重新上架。这一步一整套流程串下来就构成了租赁业务的核心闭环。2.3 登录鉴权为什么用 JWT 而不是 Session前后端分离的项目里Session 方案有一个明显的问题前端和后端不在同一个域名和端口下Session 的 Cookie 跨域管理很麻烦需要额外配置 CORS 的 allowCredentials而且服务端要维护 Session 状态在集群部署时还得引入 Session 共享的中间件。这套项目用的是 JWTJSON Web Token方案。用户在登录接口提交账号密码后端校验通过后生成一段包含用户 ID 和角色信息的加密令牌返回给前端。前端把令牌存在 localStorage 或 Vuex 里每次请求通过 axios 拦截器在请求头加上 Authorization 字段。后端写一个拦截器统一校验令牌的合法性和有效期。JWT 方案对小型项目最友好的地方在于无状态——后端不用存储会话信息令牌自带用户身份校验只是验签和解码的过程。即使将来要扩展多个服务实例JWT 也能直接通用。3. 数据库设计与实现细节3.1 核心表结构与字段设计数据库是这套项目的根基。先看核心表的划分用户表、房源表、租赁合同表、账单表、预约表、报修表、公告表。下面重点拆一下核心表的设计思路。用户表user的字段包括id、username、password、real_name、phone、role、avatar、create_time。密码字段这里要强调一下不要用明文存储至少用 MD5 加盐或者 BCrypt 加密。很多毕设项目都在密码这块翻车答辩时老师问一句“密码安全性怎么保证”就答不上来。房源表house字段包括id、title、description、address、area、room_count、hall_count、rent、deposit、status0待租、1已租、2下架、cover_img、images、user_id房东ID、create_time、update_time。这里的 status 字段是整个房源管理的灵魂后面会单独讲状态流转。租赁合同表rental_contract字段包括id、contract_no、house_id、landlord_id、tenant_id、start_date、end_date、rent、deposit、payment_method、status、create_time。contract_no 建议用时间戳加随机数生成避免手动输入重复。账单表bill字段包括id、contract_id、bill_month、rent_fee、water_fee、electric_fee、total_fee、status0未缴、1已缴、pay_time、create_time。账单不像商品订单那样有一个多变的金额流程这里字段相对固定按月生成。预约表appointment和报修表repair_order结构相对简单核心字段就是关联用户和房源、记录状态和时间。这里不一一列举数据库脚本里都有现成字段。3.2 房源状态流转的底层逻辑房源状态是租赁系统里最关键的字段它的流转规则对应着真实业务场景初始状态是 0待租租客可以浏览和预约。租客预约看房通过后如果双方达成一致并签订合同房源状态改为 1已租此时其他租客无法预约这套房源。合同到期或提前退租房源状态从 1 改回 0待租进入下一轮招租周期。房东可以把房源手动下架2比如房屋需要装修维护暂时不对外出租。这里要避免的一个设计错误是把状态散落在多个表里在合同表里存一个状态、在房源表里又存一个状态结果两边对不上。正确做法是始终以房源表的状态为主要依据合同表的状态只用于跟踪合同本身的履约进度生效中、已到期、已终止。改状态的动作必须在同一个事务里完成比如创建合同时既要插入合同记录又要更新房源状态一个事务失败就全部回滚。3.3 表关联与索引设计的三个注意点设计这套表的时候我有几个直接的经验想分享第一尽量使用逻辑外键而不是数据库物理外键。不用每条记录都强关联约束而是在 service 层做校验。这样做的原因是方便后续扩展——比如将来要拆分服务物理外键会变成巨大的阻碍。实际开发中大多数团队都采用逻辑外键。第二热点查询字段要建索引。房源列表页的筛选条件通常包含状态、租金区间、区域所以 house 表的 status、rent、address 字段建议建普通索引用户表的 username 是登录查询的入口必须建唯一索引合同表的 house_id 和 tenant_id 也建议建索引。第三金额字段用 decimal 类型不要用 float 或者 double。MySQL 里 float 是近似值存储算总费用时会出现 0.10.2 不等于 0.3 的诡异问题。账单表的 rent_fee、water_fee、electric_fee 全部用 decimal(10,2)这是跟钱有关的硬性规范。4. 后端核心功能实现与关键代码解析4.1 工程结构与分层规范后端工程的基础结构我按标准的三层架构来组织包名规则是 com.xxx.rentalcontroller接收前端请求做参数校验和统一响应封装service业务逻辑层处理核心业务规则mapper数据访问层继承 BaseMapperentity实体类对应数据库表dto前端传入参数的封装对象vo返回给前端的数据对象config拦截器、跨域、分页插件等配置utilsJWT 工具类、日期工具类等common统一返回结果、全局异常处理这里有个细节值得留意controller 里不写业务逻辑只做参数接收和结果返回。业务逻辑下沉到 service 层事务边界也在 service 层标注。这样做的价值在于当业务规则复杂时比如创建合同要同时改房源状态事务控制比较清晰不会出现同一事务里的代码散落在多个方法中的情况。4.2 JWT 登录鉴权的完整实现登录接口的逻辑并不复杂接收用户名密码查询用户是否存在、密码是否正确然后生成令牌返回。// 登录接口核心逻辑 PostMapping(/login) public Result login(RequestBody LoginDTO loginDTO) { User user userService.findByUsername(loginDTO.getUsername()); if (user null || !passwordEncoder.matches(loginDTO.getPassword(), user.getPassword())) { return Result.error(用户名或密码错误); } // 生成JWT令牌有效期24小时 String token JwtUtil.generateToken(user.getId(), user.getRole()); MapString, Object data new HashMap(); data.put(token, token); data.put(user, user); return Result.success(data); }JWT 工具类的核心逻辑是生成和解析两个方法生成时设置用户 ID、角色和过期时间解析时用固定密钥验签public static String generateToken(Long userId, Integer role) { return JwtUtil.builder() .setSubject(String.valueOf(userId)) .claim(role, role) .setIssuedAt(new Date()) // 过期时间设置成了24小时实际项目中可以按需调整 .setExpiration(new Date(System.currentTimeMillis() 24 * 60 * 60 * 1000)) .signWith(SignatureAlgorithm.HS256, SECRET_KEY) .compact(); }过滤器或拦截器要做的事从请求头 Authorization 里取出 token解析成功就把用户 ID 放进 request 的 attribute 里后续接口直接从 request 里拿当前登录用户。public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { if (OPTIONS.equalsIgnoreCase(request.getMethod())) { return true; // 跨域预检请求直接放行 } String token request.getHeader(Authorization); if (token null || !JwtUtil.verify(token)) { // 返回未授权状态码 response.setStatus(401); return false; } return true; }踩过的坑跨域时浏览器会先发一个 OPTIONS 预检请求这个请求不会携带业务请求头如果不直接放行前端会一直报跨域错误但真正的原因其实是拦截器把预检请求拦了。4.3 房源多条件分页查询的实现房源列表页是最常用的功能筛选条件包含区域省份/城市/具体位置、租金区间、户型、朝向、状态。这种多条件组合查询用 MyBatis Plus 的 QueryWrapper 构造器实现非常方便public PageResultHouseVO searchHouse(HouseQueryDTO dto) { PageHouse page new Page(dto.getPageNum(), dto.getPageSize()); QueryWrapperHouse wrapper new QueryWrapper(); // 区域条件地址模糊查询 if (StringUtils.hasText(dto.getAddress())) { wrapper.like(address, dto.getAddress()); } // 租金区间条件 if (dto.getMinRent() ! null) { wrapper.ge(rent, dto.getMinRent()); } if (dto.getMaxRent() ! null) { wrapper.le(rent, dto.getMaxRent()); } // 状态条件0待租、1已租、2下架 if (dto.getStatus() ! null) { wrapper.eq(status, dto.getStatus()); } wrapper.orderByDesc(create_time); PageHouse result houseMapper.selectPage(page, wrapper); return convertToPageResult(result); }这套查询逻辑的关键点是前端把筛选参数封装成一个对象传到后端后端通过 QueryWrapper 动态拼接 SQL 条件。搜索条件为空时少拼接一个条件即可不需要写多个 if 嵌套的 XML SQL可维护性很好。排序统一按创建时间倒序让最新发布的房源排在最前面。4.4 合同创建与账单生成的闭环逻辑租房流程走到签约这一步后端要同时完成好几件事校验房源状态是待租、校验租客没有未结清的合同、创建合同记录、修改房源状态为已租、生成第一期账单。任何一个步骤失败数据都不能出现半更新状态所以整个逻辑放在一个事务方法里Transactional(rollbackFor Exception.class) public void createContract(CreateContractDTO dto) { // 1. 确认房源仍然处于待租状态 House house houseMapper.selectById(dto.getHouseId()); if (house null || house.getStatus() ! 0) { throw new BusinessException(房源不存在或已被租出); } // 2. 创建合同记录 RentalContract contract new RentalContract(); contract.setHouseId(dto.getHouseId()); contract.setLandlordId(dto.getLandlordId()); contract.setTenantId(dto.getTenantId()); contract.setStartDate(dto.getStartDate()); contract.setEndDate(dto.getEndDate()); contract.setRent(house.getRent()); contract.setDeposit(house.getDeposit()); contract.setStatus(1); // 生效中 contractMapper.insert(contract); // 3. 修改房源状态为已租 house.setStatus(1); houseMapper.updateById(house); // 4. 生成首期账单 Bill bill new Bill(); bill.setContractId(contract.getId()); bill.setBillMonth(dto.getStartDate().substring(0, 7)); bill.setRentFee(house.getRent()); bill.setWaterFee(BigDecimal.ZERO); bill.setElectricFee(BigDecimal.ZERO); bill.setTotalFee(house.getRent()); bill.setStatus(0); // 未缴 billMapper.insert(bill); }这里有三个实际经验想强调第一创建合同前必须校验房源状态不能用前端传来的状态值做判断要重新从数据库查一次。前端是可以被改的这个校验必须放在后端。第二生成账单的月份直接用合同开始日期截取这样逻辑最简单。后续每月账单靠定时任务生成也可以用调度框架但小型系统里写一个每月跑一次的定时任务就足够了。第三事务只标注在 service 层的方法上不要在 controller 加。事务的作用范围越小对性能的影响越小也越容易定位问题。5. Vue 前端核心功能与页面实现5.1 前端工程结构与路由守卫前端工程用 Vue CLI 初始化配合 Vue Router 和 VuexUI 组件库选 Element UI。目录结构按模块划分views 放页面组件、router 放路由配置、api 放接口请求方法、utils 放请求封装和工具函数、store 放全局状态。路由守卫是前端权限控制的关键。根据当前登录用户的角色动态生成可访问的菜单租客和房东看到的侧边栏是不一样的router.beforeEach((to, from, next) { const token localStorage.getItem(token); if (to.path /login) { next(); } else { if (!token) { next(/login); } else { // 检查当前用户角色是否有权限访问目标路由 const role store.state.user.role; if (to.meta.roles !to.meta.roles.includes(role)) { next(/403); } else { next(); } } } });路由配置时在 meta 里声明该页面允许哪些角色访问比如房源管理页的 meta.roles 设置为 [0, 1]表示管理员和房东能进。这样后端有拦截器前端有路由守卫形成双重校验。5.2 axios 封装与统一响应处理接口请求统一走封装好的 request.js这一步虽然不是核心业务但属于前端工程化的基础操作。好处是所有接口的错误处理逻辑可以收敛到一个文件里不用每个页面重复写错误提示。具体做法是axios 实例设置 baseURL 指向后端服务地址请求拦截器从 localStorage 取出 token 加到请求头响应拦截器统一处理返回码401 时跳转登录页业务错误码弹出提示消息。request.interceptors.request.use(config { const token localStorage.getItem(token); if (token) { config.headers[Authorization] token; } return config; }); request.interceptors.response.use( response { const res response.data; // 统一返回格式code 为 200 表示业务成功 if (res.code 200) { return res; } else { Message.error(res.message || 请求失败); return Promise.reject(new Error(res.message)); } }, error { if (error.response error.response.status 401) { // 令牌过期清空登录状态并跳转登录页 localStorage.removeItem(token); router.push(/login); } Message.error(网络异常请稍后重试); return Promise.reject(error); } );5.3 核心页面的交互逻辑拆解房源列表页使用 Element UI 的 el-card 做卡片式布局每张卡片展示房源封面图、标题、地址、租金和面积底部还要有一个“详情”按钮和一个“预约看房”按钮。筛选栏放在列表页顶部包含省市区下拉、租金区间输入和户型选择点击查询按钮触发列表接口重新请求。房源详情页展示多张图片、户型信息、配套设施、房东信息。租客在当前页面点击“预约看房”弹出对话框选择预约日期和时间段提交后生成预约记录。房东视角下详情页会多出“编辑房源”和“上下架”按钮。个人中心与账单页面租客登录后能看到自己的合同列表每条合同右侧是账单信息未缴账单有“去缴费”按钮。这个页面的数据是一对多关系一个合同下面有多条账单前端展开行或者点击进入详情查看账单明细。写前端页面有一个实际的建议不要一上来就写组件先把静态页面搭出来用假数据填充确认页面样式和交互流程符合预期后再接后端接口。很多新手直接写接口调用结果接口还没写完页面调试无从下手反而拖慢进度。5.4 前后端联调的跨域处理开发环境下的跨域问题是联调时碰到的第一个坎。前端跑在 8080 端口后端跑在 9090 端口浏览器默认会拦截跨域请求。解决办法是前端配置 devServer 代理把请求转发到后端地址module.exports { devServer: { port: 8080, proxy: { /api: { target: http://localhost:9090, changeOrigin: true, pathRewrite: { ^/api: } } } } };这种方案的优点是部署到生产环境时只要前端把请求路径发到同一个域名的反向代理路径下后端不需要做任何域名相关配置联调期和后期的部署都能平滑过渡。如果不想用代理也可以在后端写一个跨域配置类允许指定来源跨域但开发阶段两种方式只选一种即可两个都配置也不会冲突只是多一层保证。我个人的建议是用 devServer 代理这种方式因为它可以顺便解决开发环境的 API 地址配置问题前端代码里不用写死后端地址后续部署也灵活。6. 部署运行与环境配置实录6.1 从零到跑通的完整操作步骤我整理了一下在这个项目上从零到全部跑通的操作序列按顺序执行基本不会出问题环境准备JDK 8 或 11、Maven 3.6、Node.js 14、MySQL 5.7、IDEA、VSCode 或 WebStorm。版本要求不需要最新稳定即可。第一步导入数据库。用 Navicat 或命令行执行项目提供的 SQL 脚本创建数据库和表结构同时插入初始数据。注意检查 SQL 脚本里的字符集设置如果是 utf8mb4对应创建数据库时也指定相同的字符集避免中文乱码。第二步启动后端。用 IDEA 打开后端代码Maven 会自动下载依赖。等待依赖下载完成后检查 application.yml 里的数据库连接配置改成自己本地的数据库名、用户名、密码。然后运行启动类看到 Spring Boot 的启动日志出现“Started Application in X seconds”说明启动成功。第三步启动前端。用 VSCode 打开前端文件夹终端执行 npm install 安装依赖这个过程耗时取决于网络状况和机器性能。安装完成后执行 npm run serve控制台出现编译成功日志访问 localhost:8080 就能看到登录页面。第四步验证功能。先用管理员账号登录检查房源管理、用户管理、公告管理是否正常然后切换房东账号发布一套房源再切换租客账号去看房预约走一遍核心流程。每个模块都点一遍确认页面没有报错后再交付。6.2 常见问题排查与解决方案速查表我按照自己实操中遇到问题的概率从高到低排列整理了一张问题速查表问题现象可能原因解决方案Maven 依赖下载超时或卡住默认中央仓库网络不稳定在 settings.xml 配置阿里云镜像仓库后端启动失败报数据库连接错误application.yml 地址或密码配错、MySQL 未启动核对连接字符串、确认 MySQL 已启动前端 npm install 卡住npm 默认源下载慢设置淘宝镜像源npm config set registry https://registry.npmmirror.com接口请求报跨域错误前端地址与后端地址不一致、代理配置错误检查 devServer proxy 配置或后端加 CORS 配置接口请求返回 401token 过期或未正确携带检查 axios 请求拦截器是否把 token 放到请求头页面白屏控制台报错Vue 组件引入路径错误或者依赖版本冲突查看具体报错信息修复 import 路径数据库表里中文乱码数据库和表字符集不是 utf8mb4修改数据表和连接串的字符集参数端口被占用某个服务已经占用了 8080 或 9090找到占用进程并关闭或修改启动端口这里特别想说一下 Maven 和 npm 的镜像配置问题。很多人在环境配置环节就卡住了其实不是技术问题就是下载源太慢。配置好国内镜像之后两个工具的运行速度几乎翻倍提升。6.3 二次开发与扩展方向如果这个项目你已经跑通了还想在上面做一些增量工作有几个方向可以参考第一接入 Redis 做缓存。目前热门房源列表每次刷新都会查全表数据量小感觉不到压力但房源数据量上来之后查询延迟会变明显。可以把状态为待租的房源列表缓存到 Redis设置一个合理的过期时间比如 5 分钟减少数据库压力。第二用 MinIO 替换本地文件存储。目前房屋图片是保存在本地目录的这个方案在部署到服务器时容易丢文件。MinIO 是一个开源的对象存储服务支持在 Spring Boot 里集成通过一个配置类和一个上传工具类就能完成对接。上传接口返回文件地址前端直接用这个地址展示图片相比起本地存储可靠很多。第三在房源详情页增加 VR 看房或者视频看房。可以考虑把房屋视频上传到对象存储前端通过 M3U8 协议做流媒体播放这样做的好处是支持编码和断点播放房源展示的效果会比静态图片好很多。Vue 端可以搭配原生 video 标签配合 hls.js 播放器实现不需要额外安装桌面播放器。第四增加定时任务自动生成本月账单。可以在 Spring Boot 里加一个 Scheduled 定时任务每月 1 号扫描所有生效中的合同为每个合同自动生成当月的账单记录避免手动触发。这几个扩展方向在热门搜索词里都有对应技术点说明市场的需求确实存在。选一个方向去深入结合毕设答辩的提问环节可以讲出很多技术深度。最后分享一点我在实际操作中的体会做一个完整项目最大的门槛往往不是某个技术难点而是对整体流程的把控。从设计表结构到后端接口再到前端页面最后把整条链路跑通每一步都环环相扣。这个房屋租赁系统麻雀虽小五脏俱全把这条链路完整走一遍对 Spring Boot Vue 开发的理解绝对比看一百篇教程都扎实。如果你正在找毕设项目或者想学习前后端分离项目的完整流程我建议直接用它跑一遍然后再按自己的需求改一版收获会非常不一样。
返回列表