news 2026/9/1 19:30:37

SpringBoot+Vue3个人博客管理系统实战:前后端分离从部署到上线

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SpringBoot+Vue3个人博客管理系统实战:前后端分离从部署到上线

这次我们来看一个特别适合毕设、简历项目和前后端分离入门的实战项目:基于 SpringBoot + Vue3 的个人博客管理系统。

这个项目的价值不在于概念多新,而在于它把一条完整的技术链路跑通了:SpringBoot 提供后端 REST API,Vue3 + Vite 提供前端页面,MySQL 做数据持久化,再配合一套标准的管理后台,实现文章发布、分类管理、标签管理、评论管理等日常功能。对外展示端和管理后台都齐全,增删改查全覆盖,还带完整源码和项目文档,拿来写课程设计、毕业设计,或者作为面试项目去讲,都很合适。

如果你正在找 SpringBoot + Vue3 的前后端分离项目实战素材,或者想快速掌握前后端联调、数据库增删改查这些核心套路,这篇文章可以直接收藏。下面我按“项目能做什么 -> 环境准备 -> 启动部署 -> 功能验证 -> 接口测试 -> 常见排查 -> 工程建议”的顺序,把整套系统的落地过程拆开讲清楚。

1. 核心能力速览

能力项说明
项目类型前后端分离的个人博客管理系统
后端技术栈SpringBoot、MyBatis-Plus(或 JPA,以实际源码为准)、MySQL
前端技术栈Vue3、Vite、Vue Router、Pinia、Element Plus 等
主要功能文章增删改查、分类管理、标签管理、评论管理、用户登录、个人中心
包含内容完整源码、项目文档、数据库初始化脚本
启动方式后端 Maven 启动 + 前端 npm 启动
是否支持接口 API是,后端提供 RESTful 风格接口
是否支持批量任务基础版支持批量删除,可自行扩展批量导入
推荐硬件普通开发机即可运行,内存 8G 以上更稳
适合场景毕设、课设、简历项目、前后端分离入门学习

从材料看,这个项目主打的是“全流程可跑通、增删改查全覆盖、带文档”。它的优势不一定是某条技术用得多深,而是结构完整、上手成本低,适合快速积累一个能讲清楚、能演示、能扩展的实战项目。

2. 适用场景与使用边界

这个项目适合三类人。第一类是准备毕业设计的学生,博客管理系统是一个经典题目,功能边界清晰、评审容易理解、工作量适中,不太容易出现“题目太大做不完”的情况。第二类是正在找工作的 Java 开发新人,简历上写“基于 SpringBoot + Vue3 的前后端分离博客系统”,比只写框架技术栈要具体得多,面试时可以从表结构设计、接口设计、分页查询、登录鉴权、部署方式等多个方向展开。第三类是刚学完 SpringBoot 和 Vue3 基础、想找一个完整项目练手的开发者,通过这个项目能看到一整套真实项目的代码组织方式,而不是孤立的 CRUD 示例。

能解决的问题也很明确:前端页面如何调后端接口、后端数据如何返回 JSON、数据库表怎么设计、文件上传怎么处理、登录状态怎么校验、项目如何打包部署,这些都是实际项目中逃不开的问题。

但要注意使用边界。这个项目不应该直接当生产系统去部署,毕竟个人博客系统的并发量、安全防护、数据备份方案和正式站点还有差距。如果是上线使用,需要自己补上 HTTPS、密码加密加强、接口限流、图片 CDN、日志监控这些能力。另外,如果用来做毕设或简历项目,建议自己把代码完整过一遍,尤其是表设计和接口实现,避免在答辩或面试时被问到细节却答不上来。

还有一个合规提示:博客系统涉及用户发布内容和评论,如果你后续用它做公共访问,需要考虑内容审核机制,避免出现违规内容;如果导入他人文章作为演示数据,请确保内容有授权或使用自己的原创内容。图像、字体、素材等资源也要注意版权。

3. 环境准备与前置条件

部署这套系统前,先确认本机环境。不同版本的 SpringBoot 对 JDK 的要求不同:SpringBoot 2.x 通常需要 JDK 8 或 JDK 11,SpringBoot 3.x 需要 JDK 17。Vue3 + Vite 项目对 Node.js 版本也有要求,一般建议 Node.js 16 以上,部分较新的 Vite 版本要求 Node.js 18 或 20。

环境项建议配置
JDK8 / 11 / 17,根据 SpringBoot 版本选择
Maven3.6 以上
Node.js16 / 18 / 20,推荐 LTS
包管理器npm 或 pnpm
MySQL5.7 / 8.0
数据库客户端Navicat、DataGrip 或命令行均可
IDEIntelliJ IDEA 或 VS Code
内存8G 以上,普通开发本足够
磁盘空间预留 5G 以上,包含依赖下载和构建产物

如果你打开项目发现 SpringBoot 版本太高导致配置项不兼容,可以先检查项目里的pom.xml,确认 SpringBoot 父依赖版本,再决定使用哪个 JDK。Vue3 项目如果出现 Vite 或 Node 版本不匹配,优先检查package.json里的 Vite 版本和本地 Node 版本。

启动前先用下面几条命令确认环境版本。

java -version mvn -v node -v npm -v mysql --version

如果命令能正常输出版本号,环境基本没问题。如果某个命令提示“无法识别”,说明对应软件没有安装或没有配置环境变量,先补齐再继续。

MySQL 侧需要提前建好数据库。通常项目源码里会带上blog.sqlschema.sql之类的初始化脚本,执行一次即可创建数据库表和基础数据。如果没有脚本,也可以自己设计表,后面我会给出一个常见的表结构参考。

4. 安装部署与启动方式

4.1 获取源码与目录结构

拿到源码后,先看目录结构。典型的前后端分离项目会分成两个子目录:

blog-system/ ├── backend/ # SpringBoot 后端工程 │ ├── src/ │ ├── pom.xml │ └── sql/ └── frontend/ # Vue3 前端工程 ├── src/ ├── index.html └── package.json

后端工程通常包含controllerservicemapperentityconfig等包,前端工程包含apiviewscomponentsrouterstore等目录。先把整体结构看一遍,再逐个模块打开,启动顺序建议是:先启动 MySQL 并导入数据,再启动后端服务,最后启动前端开发服务器。

4.2 创建数据库并导入初始化脚本

在 MySQL 中创建一个数据库,例如blog_db

CREATE DATABASE IF NOT EXISTS blog_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

然后使用数据库客户端导入项目提供的 SQL 初始化脚本。如果没有现成脚本,可以参考下面这套最小表结构设计。

-- 用户表 CREATE TABLE `sys_user` ( `id` bigint NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL, `password` varchar(100) NOT NULL, `nickname` varchar(50) DEFAULT NULL, `avatar` varchar(255) DEFAULT NULL, `create_time` datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 文章分类表 CREATE TABLE `blog_category` ( `id` bigint NOT NULL AUTO_INCREMENT, `category_name` varchar(50) NOT NULL, `create_time` datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 文章标签表 CREATE TABLE `blog_tag` ( `id` bigint NOT NULL AUTO_INCREMENT, `tag_name` varchar(50) NOT NULL, `create_time` datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 文章表 CREATE TABLE `blog_article` ( `id` bigint NOT NULL AUTO_INCREMENT, `title` varchar(200) NOT NULL, `summary` varchar(500) DEFAULT NULL, `content` longtext, `cover_image` varchar(255) DEFAULT NULL, `category_id` bigint DEFAULT NULL, `status` tinyint DEFAULT 1 COMMENT '1:发布 0:草稿', `view_count` int DEFAULT 0, `create_time` datetime DEFAULT CURRENT_TIMESTAMP, `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 文章标签关联表 CREATE TABLE `blog_article_tag` ( `article_id` bigint NOT NULL, `tag_id` bigint NOT NULL, PRIMARY KEY (`article_id`, `tag_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 评论表 CREATE TABLE `blog_comment` ( `id` bigint NOT NULL AUTO_INCREMENT, `article_id` bigint NOT NULL, `user_id` bigint DEFAULT NULL, `content` varchar(1000) NOT NULL, `create_time` datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

这套表结构覆盖了文章、分类、标签、评论和用户五个核心模块,标签表和文章表通过中间表关联,是博客系统比较典型的设计方式。表名和字段名以实际源码为准,这里给出的是通用参考。

4.3 修改后端配置文件

导入数据后,打开后端工程的application.ymlapplication.properties,修改数据库连接信息。重点确认数据库 URL、用户名、密码。

server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/blog_db?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false username: root password: your_password driver-class-name: com.mysql.cj.jdbc.Driver mybatis-plus: mapper-locations: classpath*:mapper/**/*.xml type-aliases-package: com.example.blog.entity

如果你的 MySQL 是 5.7,需要确认driver-class-name是否兼容;如果后端用了 SpringBoot 3 和 MySQL 8,驱动一般使用com.mysql.cj.jdbc.Driver。配置里的密码一定要改成自己本机 MySQL 的实际密码,否则后端起不来。

4.4 启动后端服务

进入后端工程目录,使用 Maven 启动:

cd backend mvn spring-boot:run

也可以先打包再运行:

mvn clean package -DskipTests java -jar target/blog-backend.jar

启动后看到类似Tomcat started on port 8080的日志,说明后端服务已经起来了。这时可以先用浏览器访问一个简单的接口地址,例如http://localhost:8080/api/article/list,看是否能返回 JSON 数据。

4.5 安装前端依赖并启动 Vite 开发服务器

打开一个新的终端窗口,进入前端目录:

cd frontend npm install npm run dev

如果npm install速度较慢,可以切换到国内镜像源:

npm config set registry https://registry.npmmirror.com

依赖安装完成后,npm run dev会启动 Vite 开发服务器,默认端口一般是5173。启动成功后,终端会显示本地访问地址,例如http://localhost:5173

4.6 启动后的访问路径

打开浏览器访问http://localhost:5173,正常情况下可以看到博客系统的前台页面或后台登录页。如果你的后端端口不是 8080,或者开发环境配置了不同的接口前缀,需要检查前端src/api目录下的请求封装,确认baseURL指向正确。

常见的前后端分离联调方式是:前端开发服务器通过 Vite 代理转发请求到后端。在vite.config.js里添加代理:

import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' export default defineConfig({ plugins: [vue()], server: { host: '0.0.0.0', port: 5173, proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true } } } })

配置好代理后,前端里所有以/api开头的请求都会被转发到后端,不需要在前端代码里写死完整的后端地址,联调阶段会省很多事。

5. 功能测试与效果验证

系统启动后,按照下面的功能测试流程逐个验证。这里以“文章管理”为主线,覆盖登录、新增、查询、编辑、删除等增删改查核心操作。

5.1 登录与权限管理测试

测试目的:确认用户登录接口可用,登录状态能被正确记录。

操作步骤:在浏览器打开后台登录页,输入管理员账号和密码,点击登录。

预期结果:登录成功后跳转到后台首页,页面右上角显示当前用户昵称。

判断成功的标准:刷新页面后登录状态仍然保持,说明 token 或 session 机制生效。如果刷新后跳回登录页,说明登录状态没有持久化,需要检查后端的 token 校验逻辑或前端的路由守卫配置。

5.2 文章新增测试

测试目的:验证文章内容能否正常写入数据库,分类、标签等关联关系是否正确保存。

操作步骤:在后台管理里选择“文章管理 -> 新增文章”,填写标题、摘要、正文内容,选择分类和标签,点击发布。

预期结果:提示保存成功,文章列表出现新记录,数据库blog_article表中可以看到对应数据行。

判断成功的标准:文章详情页可以正常渲染内容,标题、封面、摘要显示正确。如果发布后列表查不到,重点排查状态字段是否写成了草稿,或前端列表接口没有加状态过滤条件。

5.3 文章列表和分页查询测试

测试目的:确认分页查询功能正常,数据量变大时能按页加载。

操作步骤:在文章列表页面切换页码、修改每页条数、按标题关键字搜索。

预期结果:列表只显示当前页数据,总数和页码渲染正确,关键字搜索能过滤出匹配结果。

判断成功的标准:后端返回的 JSON 中包含totalrecordscurrentsize等分页字段。如果分页失效,看一下后端是否配置了分页插件,以及前端是否正确传入了pageNumpageSize参数。

5.4 文章编辑测试

测试目的:验证回显和更新功能。

操作步骤:在文章列表选择一篇文章,点击编辑,确认表单能正确回显原数据,修改正文后保存。

预期结果:修改内容后列表立即更新,详情页展示修改后的内容。

判断成功的标准:数据库update_time字段自动刷新。如果回显失败,一般是接口路径没有传对 id 参数,或者前端配置的编辑页面路由缺少动态参数。

5.5 删除与回收站测试

测试目的:验证物理删除和逻辑删除的差异。

操作步骤:在文章列表点击删除,确认记录从列表中消失。

预期结果:如果是逻辑删除,数据库记录仍在但status被修改;如果是物理删除,记录直接消失。

判断成功的标准:删除后列表刷新无报错,关联的标签中间表记录也被清理。如果使用 MyBatis-Plus 的逻辑删除功能,需要在实体类的删除字段上加上@TableLogic注解,并且查询时框架会自动拼接deleted = 0条件。

5.6 分类、标签、评论模块测试

测试目的:验证关联模块的增删改查是否正常。

操作步骤:新增一个分类,给文章设置标签,在文章详情页或后台评论管理里添加评论。

预期结果:分类列表、标签列表都能与文章正常关联,评论能在文章详情页展示。

判断成功的标准:数据库关联表中能查到对应数据,前端页面联动显示正常。这里有一个常见问题:删除分类时如果该分类下还有文章,建议提示“请先处理该分类下的文章”,防止产生悬空数据。

6. 接口 API 与批量任务

这个项目后端提供的是 RESTful 风格接口。下面给出一个通用的接口设计模板,具体路径和参数需要按项目源码调整。

6.1 核心接口示例

功能请求方式接口路径
获取文章分页列表GET/api/article/list
获取文章详情GET/api/article/{id}
新增文章POST/api/article
编辑文章PUT/api/article
删除文章DELETE/api/article/{id}
获取分类列表GET/api/category/list
获取评论列表GET/api/comment/list
用户登录POST/api/auth/login

6.2 后端 Controller 模板

后端代码的分层思路是 Controller 接收请求 -> Service 处理业务逻辑 -> Mapper 操作数据库。新增文章的 Controller 大致是这样的:

@RestController @RequestMapping("/api/article") public class ArticleController { @Resource private ArticleService articleService; @PostMapping public Result save(@RequestBody Article article) { boolean success = articleService.saveOrUpdate(article); return success ? Result.success() : Result.error("保存失败"); } @GetMapping("/list") public Result page(@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "10") Integer pageSize, @RequestParam(required = false) String keyword) { return Result.success(articleService.pageQuery(pageNum, pageSize, keyword)); } @DeleteMapping("/{id}") public Result delete(@PathVariable Long id) { boolean success = articleService.removeById(id); return success ? Result.success() : Result.error("删除失败"); } }

Result是统一响应体,一般包含状态码、消息和数据三个字段。推荐保持这种封装方式,前端可以根据code字段判断请求是否成功,而不是依赖 HTTP 状态码。

6.3 前端 axios 调用示例

前端使用 axios 调用接口,推荐把请求统一封装到src/api目录。

import axios from 'axios' import { ElMessage } from 'element-plus' const request = axios.create({ baseURL: '/api', timeout: 10000 }) // 请求拦截器,自动携带 token request.interceptors.request.use(config => { const token = localStorage.getItem('token') if (token) { config.headers['Authorization'] = 'Bearer ' + token } return config }) // 响应拦截器,统一处理业务错误 request.interceptors.response.use( response => { const res = response.data if (res.code !== 200) { ElMessage.error(res.message || '请求失败') return Promise.reject(new Error(res.message)) } return res }, error => { ElMessage.error('网络异常,请稍后重试') return Promise.reject(error) } ) export function getArticleList(params) { return request.get('/article/list', { params }) } export function saveArticle(data) { return request.post('/article', data) } export function deleteArticle(id) { return request.delete(`/article/${id}`) }

这段封装代码处理了三件事:统一设置请求前缀、自动携带登录凭证、统一处理错误提示。实际项目里的拦截器还可以扩展响应结果直接返回data字段、对 401 状态码做跳转登录等逻辑。

6.4 批量任务验证

后台管理系统最常见的批量操作是批量删除。前端把选中行的 id 数组传给后端:

export function batchDeleteArticle(ids) { return request.delete('/article/batch', { data: ids }) }

后端接收 List 参数后执行批量删除:

@DeleteMapping("/batch") public Result batchDelete(@RequestBody List<Long> ids) { boolean success = articleService.removeBatchByIds(ids); return success ? Result.success() : Result.error("批量删除失败"); }

这个逻辑可以进一步扩展成批量导出、批量发布、批量导入。批量导入常见做法是前端上传 Excel 文件,后端解析后逐行写入数据库。如果你只是完成毕设,建议先把批量删除和分页查询做得扎实,这已经是面试高频考点了。

6.5 使用 Postman 或 Apifox 调试接口

接口联调时使用 Postman、Apifox 或 IDEA 自带的 HTTP Client 都可以。启动后端服务后,直接在工具里发送请求验证。下面是一个创建文章的 JSON 请求体模板:

{ "title": "SpringBoot + Vue3 博客系统搭建实践", "summary": "本文记录前后端分离博客系统的部署过程", "content": "这是一段演示正文内容,可以从简写起。", "categoryId": 1, "tagIds": [1, 2, 3], "status": 1 }

调试时重点关注三个地方:Content-Type是否设置为application/json、请求体字段名是否和实体类字段对应、登录接口返回的 token 是否在后续请求中带了。

7. 资源占用与性能观察

前后端分离项目跑在本地开发环境时,资源占用不算高,但仍有一些地方值得观察。

首先是后端 Java 进程的 JVM 内存。SpringBoot 默认启动时堆内存可能占用几百 MB,如果你同时开着 IDEA、MySQL、前端 Vite 服务,整体内存占用会比较明显。如果电脑内存只有 8G,开发时建议关掉不必要的浏览器标签页和后台程序。

Vite 开发服务器本身很轻量,启动快,热更新响应也快。但node_modules体积不小,安装依赖时磁盘和内存都会有一些压力。构建生产包时,前端产物体积取决于依赖的组件库大小,Element Plus 这类全量引入会把体积拉大不少,这时候可以考虑按需引入。

MySQL 侧重点是慢查询。如果文章表数据量增长到十万级以上,文章列表分页查询要关注category_idstatus等字段是否建了索引。只要给表加上合适索引,分页查询性能通常不会有明显问题。

显存这个词在这个项目里不适用,但 CPU 和内存的占用可以这样观察:Windows 打开任务管理器,Mac 打开活动监视器,启动后端和前端服务后,分别看 Java 和 Node 进程的资源占用。如果后端启动特别慢,注意观察是否在编译阶段卡住;如果前端构建报内存溢出,可以给 Node 增加内存上限:

NODE_OPTIONS=--max-old-space-size=2048 npm run build

8. 常见问题与排查方法

问题现象可能原因排查方式解决方案
后端启动失败,提示数据库连接错误MySQL 没启动、密码错误、数据库名错误检查 application.yml,确认 MySQL 服务状态修改配置,重启 MySQL
前端页面能打开但接口报错前后端跨域或代理配置错误查看浏览器 Network 面板,观察请求 URL在 vite.config.js 里配置 proxy
登录后无法保持状态token 未持久化或拦截器未生效查看 localStorage 中是否有 token检查登录接口的返回处理和请求拦截器
SpringBoot 版本太高,配置不兼容项目使用 SpringBoot 3,本机 JDK 是 8查看 pom.xml 中 SpringBoot 版本,检查 JDK 版本使用 JDK 17,或回退 SpringBoot 2.x
前端依赖安装失败Node 版本不匹配、网络问题、镜像源不稳检查报错信息,查看 Node 版本升级/降低 Node,换 npm 镜像源
接口返回 404请求路径错误,或前后端路径不一致对比前端接口调用路径和后端 Controller 的 @RequestMapping统一路径,重启服务
分页查询不生效缺少分页插件配置查看后端日志,观察 SQL 语句配置 MyBatis-Plus 分页插件
删除数据时报外键约束错误有关联表数据未清理查看报错信息,检查外键关联先删除关联数据或使用级联删除

这里重点说两个最常见的坑。

第一个是端口冲突。前端 Vite 默认 5173 端口,后端 SpringBoot 默认 8080 端口,如果被占用,启动时会直接报Port already in use。解决方式很简单,换一个端口即可。后端换端口就改application.yml里的server.port,前端换端口就在vite.config.js里改server.port

第二个是 CORS 跨域问题。如果你没有配置 Vite 代理,而是直接在前端代码里访问http://localhost:8080/api/...,浏览器会拦截跨域请求。解决跨域可以在后端加一个全局跨域配置,也可以使用 Vite 代理。对开发联调来说,Vite 代理更简单,推荐优先配置。

9. 最佳实践与使用建议

这套博客系统一旦跑通,建议按照工程化的思路去维护,而不是只停留在“能运行”的程度。

第一次跑通时,先不要做任何修改,按照默认数据完整走一遍:登录 -> 新增文章 -> 列表查询 -> 编辑 -> 删除。确认全流程没问题后,再开始改代码。这样能避免“改了又不知道是哪步出问题”的情况。

代码组织上,后端一定要坚持 Controller -> Service -> Mapper 三层结构,业务逻辑写在 Service 里,Controller 里只做参数接收和结果返回。很多初学者习惯把业务逻辑全写在 Controller 里,短时间能跑,但项目稍大一点就会很难维护。

前端也建议按模块组织:api目录放接口请求,views目录放页面,components目录放公共组件,router目录放路由配置,store目录放全局状态。做这个博客系统时,前端可以把路由守卫和请求拦截器这两块打磨好,面试时很加分。

数据库层面,给常用查询字段加索引,文章表内容字段用longtext,标题字段限制长度,用户密码必须加密存储。如果你的项目还停留在明文密码阶段,强烈建议改成 BCrypt 加密,这是技术债里最容易被面试官追问的一条。

批量操作和数据导入方面,建议增加操作日志。删除文章、发布文章这类操作如果没有任何记录,线上出了问题很难追溯。加日志的方式很简单,在 Service 层打印关键操作,或者写入一张日志表。

还有一点要特别提醒:不管是用作毕设还是简历项目,都要注意数据安全和内容合规。系统里如果有用户注册和评论功能,要设置内容过滤和敏感词校验,避免被恶意数据注入。演示数据建议用自己写的技术文章,不要直接抓取未经授权的第三方站点内容。如果后续把系统部署到公网,必须把默认管理员密码改掉,关闭不必要的端口,配置好数据库访问白名单。

10. 总结与下一步

这个 SpringBoot + Vue3 博客管理系统最值得尝试的点在于:它把前后端分离项目的完整链路打包成了一只手能数的核心模块,文章管理、分类管理、标签管理、评论管理、用户登录,每一个都是实际开发里高频使用的功能。你真正动手跑一遍之后,获得的不是一个“看懂了”的虚拟经验,而是一套能运行、能演示、能封装的完整代码资产。

建议你最先验证的是文章从新增到展示的全流程。其他功能都可以先放一放,先把“前端表单提交 -> 后端接收 -> 数据库存储 -> 列表回显”这条主线走通,整个项目的骨架就抓住了。

最容易踩的坑集中在两个地方:数据库连接配置和前后端联调路径。数据库连接出错,后端直接启动失败;代理配置不生效,前端页面打不开接口数据。这两个问题不出意外的话一定会遇到,遇到时对照上面第 8 节的排查表解决即可。

后续如果要在这个项目上继续扩展,方向可以从这几个维度考虑:接入 Redis 做登录会话缓存和热点文章统计,接入 ElasticSearch 做文章全文搜索,接入对象存储服务做图片上传,用 Docker 把前后端和 MySQL 打包部署,或者增加一个简单的用户中心模块,支持用户注册、个人信息编辑、我的文章列表。每加一个模块,这个项目在简历上的含金量就会再上一档。先把基础版本跑通,再基于它去做增量开发,这条路最稳。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/1 19:29:28

单片机毕业设计-基于 STM32 或 51 单片机的防干烧定量出水饮水装置设计与开发 基于 STM32 或 51 单片机与 WiFi 的智能饮水设备软硬件系统设计(024805)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机&#xff0c;Java、小程序技术领域和毕业项目实战 ✌️…

作者头像 李华
网站建设 2026/9/1 19:25:55

一次搞懂如何在Vue中构建高质量的第三方Open API适

在企业级前端工程化实践中&#xff0c;对接第三方的开放 API&#xff08;如支付网关、物流查询、地图服务或复杂的金融数据源&#xff09;是不可避免的需求。对于初级开发者而言&#xff0c;直接在组件内通过 Axios 发起请求并解析响应是一种快速实现的方式&#xff1b;然而&am…

作者头像 李华
网站建设 2026/9/1 19:25:00

WPS办公自动化:PDF批量转图片与PPT模板生成实战

WPS 超级会员、PDF 批量转图片、海量 PPT 模板、VBA 宏……这些词经常同时出现在办公软件讨论中。实际用户提到“WPS 超级会员”时&#xff0c;最常关心的其实是两件事&#xff1a;能不能把大量 PDF 文件批量处理成图片&#xff0c;以及能不能用现成 PPT 模板快速完成汇报材料。…

作者头像 李华
网站建设 2026/9/1 19:17:39

半主机模式:嵌入式printf调试的幕后机制

你 printf 调试用了四年&#xff0c;不知道半主机模式是怎么工作的&#xff1f;在嵌入式开发中&#xff0c;调试是绕不开的环节。大多数工程师从入门就开始用printf打印调试信息&#xff0c;但很少有人追问过&#xff1a;MCU 上没有屏幕&#xff0c;也没有操作系统&#xff0c;…

作者头像 李华
网站建设 2026/9/1 19:17:01

ADOFAI Speed Test实战:音频偏移与输入延迟校准指南

这次我们来看一个 ADOFAI&#xff08;A Dance of Fire and Ice&#xff0c;中文常叫《冰与火之舞》&#xff09;相关的 Speed Test 测试玩法。标题里的“PE/G7”在不同社区可能有不同含义&#xff0c;如果它是你拿到的谱面包、版本标识或难度代号&#xff0c;那先要把它当成一个…

作者头像 李华
网站建设 2026/9/1 19:16:27

FAISS 开源向量检索库深度解析:从 ANN 原理到亿级 RAG 检索实战

为什么你需要 FAISS大模型时代&#xff0c;几乎所有 AI 应用都长这个样子&#xff1a;用户提问 → 把问题变成向量&#xff08;Embedding&#xff09;→ 在知识库里找最相似的 K 条内容 → 拼进 Prompt 喂给大模型中间那步"找最相似的 K 条"&#xff0c;术语叫 最近邻…

作者头像 李华