直接上手一个 SpringBoot + Vue 博客系统,当作毕设课设的完整思路(附坑点)
每年到了毕设和课设季,后台私信里问得最多的就是类似"有没有适合练手的前后端分离项目"、"SpringBoot + Vue 的源码有没有推荐"这类问题。说实话,纯 CRUD 的管理系统一大堆,但真正适合学生拿来理解开发流程、又能在答辩时讲清楚的项目,博客系统绝对算一个。原因很简单:它的业务闭环完整——前台展示文章、后台管理内容,涉及用户、文章、分类、标签、评论这些经典实体,技术栈又能同时覆盖后端接口开发、前端页面交互、数据库设计三大块,工作量不大不小,刚好够一个学期或者一个毕业设计周期消化。
今天这篇文章,我就结合自己这些年做项目、带新人、看毕设源码的经验,完整拆解一个基于 SpringBoot + Vue + Java + MySQL 的精简博客系统管理平台。你拿到的不仅是一份源码怎么用的说明,更是从环境准备、数据库设计、后端接口、前端页面到最后的避坑指南的全套思路。不管你是正在选毕设题目,还是课设刚好卡在这个方向,这篇文章都能帮你少走很多弯路。
老实说,这种项目网上开源版本非常多,但大部分源码下载下来之后第一件事不是跑起来,而是开始无尽的环境配置地狱。所以我先给你交个底:整个项目跑通的核心难点不在业务代码本身,而在 JDK 版本、MySQL 版本、Node 版本、Maven 依赖之间的匹配关系上。我们边讲项目边把这些坑填平。
1. 项目整体设计与技术选型思路
1.1 为什么要用 SpringBoot + Vue 这套组合
先说为什么这个组合能成为毕设和课设的"标配"。SpringBoot 解决了 Java 后端开发中配置繁琐的问题,内嵌 Tomcat、自动配置、起步依赖这几个特性让新手不用理解一堆 XML 配置就能把项目跑起来。Vue 是目前国内前端使用率最高的框架之一,上手曲线平缓,配合 Element UI 或者 Element Plus 做后台管理界面,颜值和功能都有保障。
从学习价值来看,这套组合能让你一次性接触到:RESTful API 设计、MyBatis/MyBatis-Plus 数据持久化、JWT 认证机制、前端组件化开发、Axios 请求封装、路由守卫……这些都是面试时的高频考点,做完一个项目你就全串起来了。
从毕设答辩角度讲,博客系统天然适合展示:你可以现场演示文章的增删改查、分类管理、标签管理、评论审核,每个操作背后都能讲出对应的技术点,不会出现"功能太简单没东西可讲"的尴尬,也不会陷入"功能太复杂讲不清楚"的困境。
1.2 技术选型对比:为什么不推荐 SSM 或者 Python 方案
你可能见过同学用 SSM(Spring + SpringMVC + MyBatis)做毕设,或者用 Django、Flask 做博客。说实话各有各的好处,但我个人还是推荐 SpringBoot + Vue,理由有三个方面。
第一,SpringBoot 对新手最大的红利是"约定大于配置"。SSM 时代光是一个 applicationContext.xml 就能劝退无数人,SpringBoot 则把这套底层逻辑全部内聚了,你能快速进入写业务代码的状态,而不是把时间浪费在环境搭建上。
第二,前后端分离是当前企业开发的主流形态,用 SpringBoot + Vue 做毕设,你可以在答辩时理直气壮地说"这是我按照企业级开发模式完成的项目",这句话本身就加分。
第三,社区资源极其丰富。你遇到任何问题,无论是 MySQL 安装配置还是 Vue 依赖版本冲突,都能搜到大量现成答案。这一点在你赶工的时候尤其救命。
Python 方案不是不好,但如果你专业课程里以 Java 为主,用 Python 做毕设反而要吃两遍苦——一遍学业务,一遍学新语言。除非你本来就熟悉 Python,否则 Java 路线稳妥得多。
1.3 这个项目适合谁,能学到哪里
我把话说明白一些,这个项目不是那种"看起来高大上但实际无法落地"的玩具代码,它是能让你扎扎实实走完一遍开发流程的小而全项目。
适合这三类人:
- 准备做毕业设计的本科生:可以作为选题,也可以借鉴架构迁移到别的业务场景,比如秒杀系统、校园二手交易平台。核心就是一套 SpringBoot + Vue 的骨架,换换表结构就能复用。
- 课程设计或实训项目需要:一般课设要求的功能点不会太复杂,博客系统天然覆盖了"用户管理、内容管理、页面展示、数据持久化"这些常见要求,比较容易过查重和验收。
- 自学 Java 后端想找练手项目的人:你不需要把 SpringCloud 微服务那套直接上车,先从单体应用到前后端分离走通一遍,后面再学微服务就轻松很多。
通过这个项目你能学到的具体技能点包括:Maven 依赖管理机制、SpringBoot 自动配置原理、MyBatis-Plus 的 CRUD 封装与条件构造器、表结构设计中的范式与反范式取舍、Vue Router 的路由守卫、Axios 拦截器、JWT 无状态认证流程、Nginx 部署前后端分离项目的方式。
2. 环境准备四项必修课:JDK、MySQL、Maven、Node.js
2.1 JDK 版本选择与配置实操
很多同学的第一个坑就出在 JDK 上。网上教程铺天盖地,有教装 JDK 8 的,有教装 JDK 11 的,还有推荐 JDK 21 的,到底选哪个?
我的建议是:如果项目源码是基于 SpringBoot 2.x 开发的,装 JDK 8 或者 JDK 11 最稳;如果是 SpringBoot 3.x 的项目,直接上 JDK 17 或者 JDK 21。不要混用,否则要么启动直接报UnsupportedClassVersionError,要么各种依赖不兼容。很多下载的套路源码里写的是 JDK 8 的配置,你偏偏装了"最新版 JDK 21",项目一启动就报错,其实不一定是代码的问题,就是版本不匹配。
JDK 安装本身不复杂,但有两个细节值得注意。一是环境变量 JAVA_HOME 要指向 JDK 安装目录,而不是 JRE 目录;二是 PATH 里要追加%JAVA_HOME%\bin。装完之后在命令行输入java -version能正确输出版本信息才算成功。还有一个比较隐蔽的问题:Windows 上如果之前装过 Oracle 自带的老版本 JDK,注册表里可能残留旧路径,这时候建议把 PATH 里所有和 Java 相关的旧条目清理干净再添加新路径。
2.2 MySQL 8 的安装与连接调优
数据库这块,目前主流方案是 MySQL 8.0。相比 5.7,8.0 在性能、窗口函数、JSON 支持上都有明显提升,而且新版 Navicat 和 DataGrip 对 8.0 的支持也很好。
安装过程中最常见的拦路虎是"安装到最后一步 Start Service 失败"。这个问题的原因通常有两个:一是本机 3306 端口已经被占用(可能你之前装过旧版 MySQL),二是服务名称冲突。解决思路是:先netstat -ano | findstr 3306看看端口被谁占了,如果是旧版 MySQL 的服务残留,先卸载干净再装。
如果你是跟着毕设源码走,大概率会用到 MySQL 8,那就要注意驱动版本。SpringBoot 2.x 系列用com.mysql.cj.jdbc.Driver这种新驱动,而老教程里写的com.mysql.jdbc.Driver在 MySQL 8 下是会报警告甚至直接报错的。连接串里面还要加上serverTimezone=Asia/Shanghai和useSSL=false,这是另一个高频报错点。一个典型的 JDBC 连接配置长这样:
spring.datasource.url=jdbc:mysql://localhost:3306/blog?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true spring.datasource.username=root spring.datasource.password=你的密码allowPublicKeyRetrieval=true这个参数很多人不加,结果连接时卡在 "Public Key Retrieval is not allowed",其实这是 MySQL 8 默认 caching_sha2_password 认证插件导致的问题。如果你不想开这个参数,也可以在 MySQL 里把 root 用户的加密规则改回 mysql_native_password,但一般来说直接加参数更省事。
2.3 Maven 与 Node.js 环境匹配问题
Maven 的坑比较集中在仓库镜像和依赖下载上。国内网络环境下,Maven 中央仓库的访问速度慢得让人绝望,所以一定要配置阿里云镜像。
顺带说一嘴,有些 SpringBoot 项目用的依赖版本非常老,比如旧版 MyBatis 启动器在 JDK 17 下会报"IllegalAccessError"。解决方案就是升级 MyBatis 对应启动器版本,或者保持 JDK 8,二者选其一,千万不要在这个问题上死磕太久。
Node.js 这边,Vue 2 项目建议 Node 14 或 16,Vue 3 项目建议 Node 16 以上。很多做毕设的同学直接装了最新的 Node 20,然后跑 Vue 2 的老项目时就发现 node-sass 编译不过,报各种 Python 版本错误、Visual Studio 编译工具缺失。这个问题能卡你一整天。最直接的解法是:要么按源码 package.json 里的版本要求来装对应 Node,要么用 npm 的 sass 替代 node-sass。到了 Vue 3 时代,Vite 取代 Webpack,这个问题就少很多了。
还有一个值得提醒的问题:npm 默认源在国外,安装依赖速度极慢,建议直接设置淘宝镜像:
npm config set registry https://registry.npmmirror.com设置完之后再执行npm install,体感速度能快好几倍。
3. 数据库设计是整个项目的地基
3.1 博客系统的核心表结构设计
博客系统的实体关系不算复杂,但设计得好不好直接影响后面编码的幸福感。我先给你列一个比较经典的简化表设计,这是目前网上大多数开源博客系统源码的通用方案。
最核心的是用户表t_user和文章表t_article,其中文章表要冗余存储分类 id 和用户 id,避免每次查询都要 JOIN 一大圈。分类表t_category和标签表t_tag相对独立,文章和标签之间再建一张中间表t_article_tag,用来实现多对多关系。评论表t_comment要记录评论人、评论文章、父评论 id,这样可以让评论支持楼中楼。
如果用一句话总结这套设计:业务字段写得宽一点,外键关系少一点,查询性能好一点。很多学生喜欢把外键约束加得很全,但实际项目里外键在分布式和性能压力下反而成了累赘,MyBatis-Plus 时代更常见的是逻辑外键,也就是只存 id 不加物理约束。
3.2 字段类型与索引设计的经验之谈
文章内容通常比较长,MySQL 中一般用longtext或者text类型。这里有一个小技巧:文章主体用longtext,但不要把正文丢到查询列表里返回,列表页只查标题、摘要、分类、发布时间这些字段,用户点击详情再查全量内容。这样做的好处是列表接口能快不少,尤其是数据量上了几千篇之后。
分类和标签的字段要设计好逻辑唯一索引,比如分类名可以加 UNIQUE 索引,避免同样一个"Java"分类被插入两条记录。文章表一定要在category_id和user_id上建普通索引,这是高频查询条件。
我在做博客系统时还加了一个is_published字段,默认 0,只有管理员手动发布后才会变 1。前台查询只展示is_published = 1的文章。这个小设计能解决很多答辩时的尴尬问题——比如"如何实现草稿功能"。
再补充一个时间字段的设计细节:create_time和update_time都设置为 DATETIME 类型,不要用TIMESTAMP,原因是 TIMESTAMP 的范围只到 2038 年,而且存在时区转换问题,DATETIME 虽然占空间大一点,但语义更清晰。如果你用的是 MyBatis-Plus,可以直接用@TableField(fill = FieldFill.INSERT)配合 MetaObjectHandler 自动填充时间,比手动 set 要优雅很多。
3.3 初始化数据脚本的写法建议
源码包里一定要带一份init.sql,这是大学生项目最容易偷懒的地方。一份完整的初始化脚本应该包含:建库语句、建表语句、初始管理员账号的 INSERT 语句。千万不要把建表语句散落在不同文件里,也不要只提供表结构不给数据,否则评审老师或者同学拿到源码之后第一步就卡住了。
写初始化脚本时还有几个细节:
- 数据库字符集统一用
utf8mb4,不要用utf8,否则 emoji 表情入库直接变问号。 - 排序规则建议用
utf8mb4_general_ci,大小写不敏感,查询时匹配体验更好。 - 初始密码不要存明文,先找一个在线 BCrypt 工具把
admin123生成好 bcrypt 哈希,直接写进脚本里。
4. 后端核心模块实现要点
4.1 SpringBoot 项目骨架搭建与分层设计
后端代码结构网上流传比较广的标准三层结构是 controller / service / mapper,这个模式容易理解,也基本够用。但如果你希望项目在答辩时显得更专业一点,可以加上common(统一返回结果与异常处理)、config(配置类)、entity(实体类)、dto(数据传输对象)、vo(视图对象)这些包。
统一返回结果类Result是这个项目的灵魂之一。它的典型设计是所有接口都返回{ code, message, data }这样的 JSON 结构,前端封装一层 Axios 拦截器统一处理 code,就不用每个请求都单独判断成功失败。这个设计在大厂面试里经常被问,能在毕设答辩时主动讲出来会是不错的加分点。
异常处理这块,建议写一个全局异常处理器@RestControllerAdvice,把业务异常、参数校验异常、兜底异常分开处理。比如用户名重复、文章不存在这类问题抛业务异常,前端拿到之后统一弹提示。这样做的好处是你的 controller 会非常干净,每行代码都在说业务,而不是塞满了 try-catch。
4.2 MyBatis-Plus 的高效用法与翻车点
MyBatis-Plus 对于这种单体管理项目简直是效率神器。内置的BaseMapper提供了 insert、deleteById、selectById、selectPage 等常用方法,简单 CRUD 你甚至不用写 XML。
但这里有几个翻车点值得注意。
第一,实体类的驼峰字段自动映射依赖一个配置:map-underscore-to-camel-case: true。SpringBoot 的application.yml里要显式打开这个配置,否则数据库里的user_name映射不到实体类的userName属性上。
第二,分页查询必须配置 PaginationInnerInterceptor,否则你调用selectPage发现它只是假分页,把所有数据都查出来了。正确的配置方式是在 config 包里注入 MybatisPlusInterceptor 的 Bean。
第三,逻辑删除要加@TableLogic注解。现在很多管理系统都要求不物理删除,而是打一个deleted标记,MyBatis-Plus 对这个支持得很好,但前提是你得在每个实体类的逻辑删除字段上加上这个注解,否则删除操作就真的把记录抹掉了。
4.3 基于 JWT 的登录认证与权限控制
博客系统管理平台是有身份区分的,最简单的模型就是"管理员"和"普通用户",而 JWT 是这个场景下最通用的方案。
JWT 的流程不复杂:用户登录成功后,后端用秘钥生成一个 token 串返回给前端,前端存到 localStorage 或者 sessionStorage,之后每次请求在 header 里带上Authorization: Bearer token。后端写一个过滤器,拦截需要认证的请求,解析 token 拿到用户 id 和角色信息,放行或者拒绝。
这个方案的关键是如何区分"需要登录的接口"和"不需要登录的接口"。一般博客前台的文章列表和详情其实是公开的,不能说没登录就不能看文章。而文章的新增、删除、修改操作必须是管理员权限。所以你在写配置时可以用拦截器注册表来指定要拦截的路径,比如/admin/**开头的接口全部要认证,并且角色必须为 admin。这比一股脑全拦截要合理很多。
写 JWT 工具类时有几个封装细节要做好:
- 过期时间设置不要超过 24 小时,除非你有 refresh token 机制,否则用户改一次密码还得等 token 过期,体验很差。
- 秘钥要放到配置文件中,不要写死在代码里。
- 解析 token 时要捕获所有异常,包括过期异常和签名异常,统一返回 401,让前端跳回登录页。
4.4 接口设计规范与防御性编程
接口设计这块,我见过太多学生项目全是模糊的/query、/update,这样看起来项目质量很低。建议按照 REST 风格来设计,比如获取文章列表用GET /api/articles,新增文章用POST /api/articles,删除文章用DELETE /api/articles/{id}。
后端参数校验也是很多源码不动的地方。其实只要在实体字段上加上@NotBlank(message = "标题不能为空"),然后 controller 参数前面加@Validated,就能自动完成入参校验,省掉大量手写 if 判断。
再聊一下防 SQL 注入的问题。用 MyBatis 的#{}传参,PreparedStatement 会自动做参数化处理,这是安全的。但如果你图省事用了${},就存在注入风险。规范做法是整个项目禁用${},即便要动态排序也要用白名单方式。
5. 前端页面搭建与关键交互实现
5.1 基于 Vue 的前后台页面结构
前台展示和后台管理用同一个 Vue 项目,通过路由区分开,这样打包部署时只需要一个 dist 目录。后台管理页面用 Element Plus 的布局容器,左侧是菜单栏,包括文章管理、分类管理、标签管理、评论管理、系统设置等菜单,右侧是内容区,通过 router-view 切换组件。
前台界面则完全走另一套风格,简单干净一点就行。比较常见的结构是顶部导航栏 + 文章列表 + 侧边栏推荐 + 文章详情页。
这里有一个经验:组件按需注册,不要全部全局引入。Element Plus 全量引入会让打包体积膨胀到好几百 KB,在答辩现场页面加载慢很尴尬。按需引入配合自动导入插件,代码更干净,体积也小很多。
5.2 Vue Router 路由守卫与权限控制
前端路由守卫是配合后端 JWT 的关键环节。每个需要登录的页面都要在路由配置的 meta 里标记requiresAuth: true,然后在beforeEach里判断当前有没有 token。没有 token 直接跳转登录页,并带上 redirect 参数,登录成功后回跳原页面。这个回跳细节很多源码都没做,但面试时被问过,建议你实现一下。
如果涉及管理员和普通用户的菜单差异,可以在路由守卫里再从 localStorage 取出当前用户的角色信息,和后端返回的菜单列表比对,动态过滤路由。不过这个动态路由的实现有点工作量,如果你只是做课设,做到"没有 token 不让进后台"这一档就够用了。
5.3 Axios 封装与拦截器实战
Axios 封装是前端工程质量的分水岭。简单项目中到处this.$http.get()虽然能用,但一旦要统一处理错误提示、token 过期跳转、文件上传 token 携带,就会非常痛苦。
推荐的做法是在 src 下建一个utils/request.js,创建 axios 实例时设置 baseURL 和超时时间。请求拦截器里从 localStorage 取出 token 放到 header;响应拦截器里统一处理后端返回的 code。如果 code 是 401,就清空本地用户信息并跳转登录页。这样你在业务页面里只需要写request.get('/articles')然后处理 data 即可,代码量直接减少一半。
写这些拦截器时有一个坑:vite 或者 webpack 的 devServer 代理如果没配好,前端请求后端的接口会跨域。开发环境最常见的解决方式是配置 vite.config.js 里的 server.proxy,把/api开头的请求代理到http://localhost:8080,同时后端在WebMvcConfigurer里配置跨域规则放行本地前端地址。两边配合好,联调才能顺畅。
5.4 Markdown 编辑器与文章展示方案
写博客系统一般绕不过 Markdown 编辑器。后台管理界面里建议使用 mavon-editor(Vue 2)或 md-editor-v3(Vue 3),支持实时预览和图片上传,界面美观。前台文章展示则需要引入 markdown 解析库,把后端返回的 Markdown 原文渲染成 HTML 展示。
这里有个实际经验:在展示端渲染 Markdown 时必须做 XSS 过滤,否则评论或者文章里如果包含恶意 script 标签会直接执行。比较简单的应对方式是使用dompurify库过滤后再插入 DOM,代码量很小,能避免很多隐患。
还有视频播放问题,有些同学想在博客文章里插入本地视频,甚至有人搜过 vue 播放 m3u8 的做法。如果你不需要流媒体直播需求,用原生 html5 video 标签就能解决,如果需要 m3u8 格式的视频流,那就要引入 hls.js 这个库。不过毕设项目里我建议别过度扩展这个功能,答辩时长有限,越多的功能点反而越难讲透。
6. 常见问题与排查技巧实录
6.1 环境类问题速查表
我整理了做 SpringBoot + Vue 项目时最常遇到的几个环境类问题,方便你对症下药。
| 现象 | 可能原因 | 解决方式 |
|---|---|---|
| SpringBoot 启动时报 UnsupportedClassVersionError | JDK 版本过高或过低,与项目编译版本不一致 | 切换 JDK 版本,或修改 pom.xml 中的 java.version 参数 |
| 连接 MySQL 报 Public Key Retrieval is not allowed | MySQL 8 默认认证插件导致 | JDBC 连接串加 allowPublicKeyRetrieval=true |
| npm install 报 node-sass 编译失败 | Node 版本与 node-sass 不兼容 | 换 Node 16,或用 sass 替代 node-sass |
| Vue 打包后刷新页面 404 | 前端路由是 history 模式,后端/nginx 没有做 try_files 配置 | 部署环境配置 fallback 到 index.html |
| Maven 依赖下载超时 | 中央仓库慢或被墙 | 配置阿里云镜像或华为云镜像 |
| 端口被占用启动失败 | 8080/3306 被其他进程占用 | netstat 查端口,换端口或结束占用进程 |
6.2 后端启动与接口联调中的高频踩坑
第一个高频坑是SpringBoot 版本太高导致的各种兼容问题。比如在 SpringBoot 3.x 里,javax.*的包全部换成了jakarta.*,你从网上下载的源码如果是基于 2.x 写的,会有大量 import 报错。这种报错不是缺依赖,而是整个命名空间都变了。如果你没有把握自己迁移代码,最直接的办法是下载源码时先确认它是基于 SpringBoot 2.x 还是 3.x,对应装对 JDK 版本。
第二个高频坑是Mapper 接口扫描不到。入口类上要么加@MapperScan("com.xxx.mapper"),要么在每一个 Mapper 接口上加@Mapper注解。很多人漏了这个,启动不报错,但一调用查询就报无效绑定语句异常。
第三个高频坑是前端跨域配置不对。这需要前后端同时配合,光在后端加 @CrossOrigin 只能处理简单请求,遇到带 token 的预检请求还是会出问题。建议在 Spring Security 或者拦截器的配置文件里统一配置跨域规则,并且在前端 vite.config.js 里做好代理。
6.3 前端调试的常规操作路径
前端出问题,不要上来就改代码。先打开浏览器 F12,看 Network 面板里请求到底发出去没有,返回的状态码是什么,响应体里的 JSON 是什么。90% 的前后端联调问题都能在 Network 面板里找到答案。
如果请求是 404,先确认后端接口路径是否正确,尤其是 SpringBoot 里@RequestMapping和类上的@RestController是否拼对。如果请求是 500,看后端控制台异常堆栈,一般是数据库字段映射错误或者空指针。如果请求能通但页面没数据,打开 Console 看有没有报错,再检查 Vue 组件里是否正确使用了响应式数据。
另外,Vue 项目里常见的布局异常问题也值得一提。有些同学在 Vit 打包后部署到服务器,发现页面布局错乱,但在本地开发环境正常。这个问题大概率是打包时 publicPath 配置不对,静态资源路径变成了绝对路径。在 vite.config.js 里把base设置为'./'就能解决,在 vue.config.js 里则是publicPath: './',这个细节直接影响打包部署的成败。
6.4 从源码到自己的项目:二次开发的切入点
源码拿到手之后不要直接开始改,先把项目启动跑通,浏览一遍所有页面,搞清楚每个页面调用了哪个后端接口,数据库里有哪些表。然后试着改一个最小的功能,比如把后台的系统名称改掉,或者新增一个"友情链接"的管理模块,通过这个小改动理解整个数据流。
如果你是自己用来交课设或毕设,我特别建议加一个原创的小功能,哪怕只是给文章加个浏览量统计、给评论加个点赞功能,这样答辩时老师问"这个是你自己实现的吗"的时候,你可以底气十足地说"是的,我在原基础上做了扩展"。不加原创功能直接全盘照搬,查重和答辩这两关都很难过。
我从带新人的经验来看,最容易上手且又能体现能力的二次开发点有三个方向:
- 给文章增加 Markdown 草稿箱和定时发布功能。涉及数据库字段的补充和定时任务的使用,能聊的点很多。
- 用 Redis 做文章浏览量的缓存与异步落库。这个方向能体现你懂缓存策略,但工作量适中,适合毕设扩展。
- 前端增加暗色模式切换,并通过 localStorage 记住用户偏好。纯前端改动,适合前端薄弱又想体现一点细节的同学。
写在最后的几句心里话
做这种全栈项目,最大的敌人不是技术难,而是心浮气躁。我见过太多同学卡在环境配置上一天就放弃了,其实只要按顺序一步步来,JDK 装好、数据库建好、依赖拉好、项目启动,后面写业务代码或者改源码都会顺利很多。
我个人在实际操作中的体会是:真正让你成长的并不是把源码跑起来的那一刻,而是你遇到 bug 去查资料、试方案、解决问题的那几个小时。博客系统这个项目体量小、边界清晰,非常适合在上面练这种能力。如果你手里已经有一份能跑通的 SpringBoot + Vue 博客源码,先顺着代码读一遍,再动手改几个功能,最后能独立写出来一个简单模块,那这份源码对你的价值才算真正发挥出来了。
最后再分享一个小技巧:做项目之前一定要养成写文档的习惯,不用多正式,一个 Markdown 文件记录你改了哪些表、改了哪个接口、遇到了什么问题、怎么解决的,坚持下来你会发现毕业设计写论文的时候材料全都在手边,不用临时回忆。这套工作流本身,也是这个项目带给你的额外收获。