【2025最新版】SpringBoot3+Vue3全栈开发脚手架实战指南:从0到1搭建企业级应用架构
2026-02-04 04:22:16作者:钟日瑜
开篇:为什么这个全栈脚手架能让你开发效率提升300%?
你是否还在为这些问题困扰:
- 新项目搭建时,前后端整合要浪费3天以上?
- JWT认证、权限管理重复造轮子?
- Vue3组合式API与后端接口对接总是踩坑?
- 跨域配置、文件上传、数据校验这些"基础建设"占用大量开发时间?
读完本文你将获得:
- 一套开箱即用的SpringBoot3+Vue3全栈架构方案
- 10分钟快速启动前后端开发环境的实操步骤
- 5个企业级功能模块的完整实现代码(用户认证/权限管理/数据CRUD/文件上传/图表展示)
- 3种环境(开发/测试/生产)的无缝切换配置
- 10+个实战踩坑点与性能优化技巧
项目架构全景解析
技术栈选型对比表
| 技术领域 | 本项目方案 | 传统方案 | 优势说明 |
|---|---|---|---|
| 后端框架 | Spring Boot 3 | Spring Boot 2.x | 支持JDK17+,性能提升20%,原生支持虚拟线程 |
| 前端框架 | Vue 3 + Vite | Vue 2 + Webpack | 冷启动速度提升10倍,热更新速度提升5倍 |
| 数据库访问 | MyBatis-Plus | 原生MyBatis | 内置CRUD接口,减少70%重复代码 |
| 认证机制 | JWT (JSON Web Token) | Session-Cookie | 无状态设计,支持分布式部署,减轻服务器压力 |
| 前端UI | Element Plus | Element UI | 基于Vue3开发,支持按需引入,体积减少40% |
系统架构流程图
flowchart TD
Client[用户浏览器] --> |HTTP请求| Vue3Frontend[Vue3前端应用]
Vue3Frontend --> |API调用| SpringBootBackend[SpringBoot3后端服务]
SpringBootBackend --> |认证校验| JWTFilter[JWT过滤器]
JWTFilter --> |权限检查| SecurityConfig[Spring Security配置]
SecurityConfig --> |业务逻辑| Controller[控制器层]
Controller --> |数据处理| Service[服务层]
Service --> |数据库操作| Mapper[MyBatis-Plus映射层]
Mapper --> MySQL[(MySQL数据库)]
Service --> |缓存操作| LocalCache[本地缓存]
Controller --> |文件处理| FileUpload[文件上传服务]
FileUpload --> FileSystem[(文件系统)]
核心功能模块详解
1. 用户认证与权限管理
数据模型设计
-- 用户表结构
CREATE TABLE `sys_user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '登录账号',
`password` varchar(255) NOT NULL COMMENT '加密密码',
`nickname` varchar(255) DEFAULT NULL COMMENT '用户昵称',
`avatar` varchar(255) DEFAULT NULL COMMENT '头像URL',
`sex` char(1) DEFAULT NULL COMMENT '性别(0:男,1:女)',
`phone` varchar(11) DEFAULT NULL COMMENT '手机号',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 角色表结构
CREATE TABLE `sys_role` (
`id` bigint(20) NOT NULL,
`role_name` varchar(255) DEFAULT NULL COMMENT '角色名称',
`role_key` varchar(255) DEFAULT NULL COMMENT '角色标识',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 用户角色关联表
CREATE TABLE `sys_user_role` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) DEFAULT NULL,
`role_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
JWT认证实现代码
后端JWT工具类:
@Component
public class JwtUtils {
@Value("${jwt.secret}")
private String secret;
@Value("${jwt.expiration}")
private long expiration;
// 生成token
public String generateToken(LoginUser loginUser) {
Map<String, Object> claims = new HashMap<>();
claims.put("userId", loginUser.getId());
claims.put("username", loginUser.getUsername());
claims.put("roles", loginUser.getRoles());
return Jwts.builder()
.setClaims(claims)
.setExpiration(new Date(System.currentTimeMillis() + expiration))
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}
// 从token中获取用户信息
public Claims getClaimsFromToken(String token) {
return Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
}
// 验证token是否过期
public boolean isTokenExpired(String token) {
Date expiration = getClaimsFromToken(token).getExpiration();
return expiration.before(new Date());
}
}
前端请求拦截器:
// 请求拦截器
instance.interceptors.request.use((config) => {
const token = localStorage.getItem("token");
// 白名单外的请求添加token
if (whiteList.indexOf(config.url) === -1 && token) {
config.headers['Authorization'] = token;
}
return config;
}, (error) => {
return Promise.reject(error);
});
2. 数据CRUD接口实现
以演示数据(Demo)模块为例,展示完整的前后端交互流程:
后端Controller层:
@RestController
@RequestMapping("/demo")
public class DemoController {
@Autowired
private TbDemoService demoService;
// 获取数据列表
@GetMapping("/list")
public R list(TbDemo demo, PageQuery pageQuery) {
PageInfo<TbDemo> pageInfo = demoService.selectDemoPage(demo, pageQuery);
return R.ok().put("page", pageInfo);
}
// 根据ID获取详情
@GetMapping("getById/{id}")
public R getById(@PathVariable("id") Integer id) {
TbDemo demo = demoService.getById(id);
return R.ok().put("data", demo);
}
// 新增数据
@PostMapping
public R add(@RequestBody TbDemo demo) {
demoService.save(demo);
return R.ok();
}
}
前端API调用:
// src/api/demo.js
import request from '@/utils/request';
export function getDemoList(params) {
return request({
url: '/demo/list',
method: 'get',
params
});
}
export function getDemoById(id) {
return request({
url: `/demo/getById/${id}`,
method: 'get'
});
}
export function addDemo(data) {
return request({
url: '/demo',
method: 'post',
data
});
}
前端页面组件:
<template>
<div class="demo-container">
<el-table v-loading="loading" :data="demoList">
<el-table-column prop="id" label="ID" width="80" />
<el-table-column prop="name" label="名称" />
<el-table-column prop="age" label="年龄" width="80" />
<el-table-column prop="createTime" label="创建时间" width="180" />
<el-table-column label="操作" width="120">
<template #default="scope">
<el-button size="small" @click="handleEdit(scope.row)">编辑</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
:total="total"
v-model:page="pageNum"
v-model:page-size="pageSize"
@current-change="handlePageChange"
/>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import { getDemoList } from '@/api/demo';
const demoList = ref([]);
const total = ref(0);
const pageNum = ref(1);
const pageSize = ref(10);
const loading = ref(false);
const getList = async () => {
loading.value = true;
try {
const res = await getDemoList({
pageNum: pageNum.value,
pageSize: pageSize.value
});
demoList.value = res.page.list;
total.value = res.page.total;
} finally {
loading.value = false;
}
};
const handlePageChange = (page) => {
pageNum.value = page;
getList();
};
onMounted(() => {
getList();
});
</script>
3. 文件上传功能
后端文件上传控制器:
@RestController
public class UploadController {
@Autowired
private UploadService uploadService;
@PostMapping("upload")
public R upload(@RequestParam("file") MultipartFile file) {
String url = uploadService.uploadFile(file);
return R.ok().put("url", url);
}
}
文件上传工具类核心代码:
public class FileUploadUtils {
/**
* 上传文件
*/
public static String upload(MultipartFile file, String baseDir) throws IOException {
// 获取文件扩展名
String extension = FilenameUtils.getExtension(file.getOriginalFilename());
// 生成唯一文件名
String fileName = UUID.randomUUID().toString() + "." + extension;
// 按日期创建目录
String datePath = new SimpleDateFormat("yyyy/MM/dd").format(new Date());
String filePath = baseDir + datePath + "/";
File destFile = new File(filePath + fileName);
// 确保目录存在
if (!destFile.getParentFile().exists()) {
destFile.getParentFile().mkdirs();
}
// 保存文件
file.transferTo(destFile);
// 返回访问URL
return "/profile/" + datePath + "/" + fileName;
}
}
环境搭建与部署指南
快速启动步骤
1. 环境准备
| 环境依赖 | 版本要求 | 验证命令 |
|---|---|---|
| JDK | 17+ | java -version |
| Node.js | 16+ | node -v |
| MySQL | 5.7+ | mysql -V |
| Maven | 3.6+ | mvn -v |
2. 项目获取与初始化
# 克隆项目代码
git clone https://gitcode.com/weixin_46699933/SpringBoot3-Vue3-Demo
# 进入项目目录
cd SpringBoot3-Vue3-Demo
3. 数据库配置
-- 创建数据库
CREATE DATABASE IF NOT EXISTS test CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 导入SQL文件
USE test;
SOURCE demo-admin/sql/test.sql;
4. 后端配置修改
# demo-admin/src/main/resources/application-dev.yml
spring:
datasource:
url: jdbc:mysql:///test?serverTimezone=GMT%2B8&userUnicode=true&characterEncoding=utf8
username: 你的数据库用户名
password: 你的数据库密码
5. 后端启动
# 进入后端目录
cd demo-admin
# 使用Maven启动
mvn spring-boot:run
6. 前端启动
# 进入前端目录(新开终端)
cd demo-vue
# 安装依赖
npm install
# 启动开发服务器
npm run dev
7. 访问应用
- 后端API地址:http://localhost:8001
- 前端页面地址:http://localhost:3000
- 默认管理员账号:admin/admin123
多环境配置方案
后端多环境配置:
# application.yml
spring:
profiles:
active: dev # 激活开发环境配置
# application-dev.yml (开发环境)
server:
port: 8001
spring:
datasource:
url: jdbc:mysql://localhost:3306/test
# application-prod.yml (生产环境)
server:
port: 80
spring:
datasource:
url: jdbc:mysql://prod-mysql:3306/prod_db
启动命令:
# 开发环境(默认)
mvn spring-boot:run
# 生产环境
mvn spring-boot:run -Dspring-boot.run.profiles=prod
前端环境配置:
# .env.development
VITE_API_BASE_URL=http://localhost:8001
# .env.production
VITE_API_BASE_URL=https://api.yourdomain.com
性能优化与扩展建议
1. 后端性能优化
-
缓存策略
@Configuration @EnableCaching public class CacheConfig { @Bean public CacheManager cacheManager() { CaffeineCacheManager cacheManager = new CaffeineCacheManager(); // 设置缓存过期时间 cacheManager.setCaffeine(Caffeine.newBuilder() .expireAfterWrite(10, TimeUnit.MINUTES) .maximumSize(1000)); return cacheManager; } } -
接口限流实现
@Component public class RateLimiterInterceptor implements HandlerInterceptor { private final RateLimiter rateLimiter = RateLimiter.create(100.0); // 限制每秒100个请求 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (!rateLimiter.tryAcquire()) { response.setStatus(429); response.getWriter().write("请求过于频繁,请稍后再试"); return false; } return true; } }
2. 前端性能优化
-
路由懒加载
// src/router/index.js const routes = [ { path: '/demo', name: 'Demo', component: () => import('@/views/sys/demo.vue') // 懒加载 } ]; -
组件按需引入
// 只引入需要的组件,减少打包体积 import { ElButton, ElTable, ElPagination } from 'element-plus';
项目目录结构详解
SpringBoot3-Vue3-Demo/
├── demo-admin/ # 后端项目
│ ├── src/main/java/cn/itzd/
│ │ ├── controller/ # 控制器层
│ │ ├── service/ # 服务层
│ │ ├── mapper/ # 数据访问层
│ │ ├── entity/ # 实体类
│ │ ├── config/ # 配置类
│ │ └── utils/ # 工具类
│ ├── src/main/resources/
│ │ ├── application.yml # 主配置文件
│ │ ├── application-dev.yml # 开发环境配置
│ │ └── application-prod.yml # 生产环境配置
│ └── sql/ # 数据库脚本
└── demo-vue/ # 前端项目
├── src/
│ ├── api/ # API接口定义
│ ├── components/ # 公共组件
│ ├── views/ # 页面视图
│ ├── router/ # 路由配置
│ ├── utils/ # 工具函数
│ └── assets/ # 静态资源
├── package.json # 项目依赖
└── vite.config.js # Vite配置
常见问题解决方案
1. 跨域问题
问题表现:前端请求后端接口时控制台出现类似错误:
Access to XMLHttpRequest at 'http://localhost:8001/api' from origin 'http://localhost:3000' has been blocked by CORS policy.
解决方案:
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOriginPatterns("*")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(3600);
}
}
2. JWT令牌过期
解决方案:前端实现令牌过期自动刷新机制
// 响应拦截器中添加token刷新逻辑
instance.interceptors.response.use(response => {
return response;
}, async error => {
const originalRequest = error.config;
// 如果是401错误且未尝试刷新token
if (error.response.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
try {
// 调用刷新token接口
const res = await refreshToken();
localStorage.setItem('token', res.token);
// 重新设置Authorization头
originalRequest.headers['Authorization'] = res.token;
// 重试原始请求
return instance(originalRequest);
} catch (err) {
// 刷新token失败,需要重新登录
localStorage.removeItem('token');
router.push('/login');
return Promise.reject(err);
}
}
return Promise.reject(error);
});
总结与展望
SpringBoot3-Vue3-Demo作为一个全栈开发脚手架,提供了企业级应用开发所需的核心功能模块和最佳实践。通过本指南的学习,你已经掌握了:
- 基于Spring Boot 3和Vue 3的现代化全栈架构搭建方法
- 用户认证、权限管理、数据CRUD、文件上传等核心功能的实现原理
- 多环境配置与项目部署的完整流程
- 性能优化与常见问题的解决方案
未来扩展方向:
- 集成Redis实现分布式缓存
- 添加消息队列实现异步处理
- 引入微服务架构实现系统解耦
- 集成ELK栈实现日志收集与分析
如果你觉得这个项目对你有帮助,请点赞、收藏并关注作者,获取更多技术干货!下期我们将带来"基于该脚手架开发企业级CMS系统"的实战教程,敬请期待!
附录:核心依赖版本清单
| 依赖名称 | 版本号 |
|---|---|
| Spring Boot | 3.0.5 |
| MyBatis-Plus | 3.5.3.1 |
| JWT | 0.11.5 |
| MySQL Connector | 8.0.32 |
| Vue | 3.3.8 |
| Element Plus | 2.4.1 |
| Vite | 5.1.0 |
| Axios | 1.3.4 |
登录后查看全文
热门项目推荐
相关项目推荐
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0153- DDeepSeek-V4-ProDeepSeek-V4-Pro(总参数 1.6 万亿,激活 49B)面向复杂推理和高级编程任务,在代码竞赛、数学推理、Agent 工作流等场景表现优异,性能接近国际前沿闭源模型。Python00
LongCat-Video-Avatar-1.5最新开源LongCat-Video-Avatar 1.5 版本,这是一款经过升级的开源框架,专注于音频驱动人物视频生成的极致实证优化与生产级就绪能力。该版本在 LongCat-Video 基础模型之上构建,可生成高度稳定的商用级虚拟人视频,支持音频-文本转视频(AT2V)、音频-文本-图像转视频(ATI2V)以及视频续播等原生任务,并能无缝兼容单流与多流音频输入。00
auto-devAutoDev 是一个 AI 驱动的辅助编程插件。AutoDev 支持一键生成测试、代码、提交信息等,还能够与您的需求管理系统(例如Jira、Trello、Github Issue 等)直接对接。 在IDE 中,您只需简单点击,AutoDev 会根据您的需求自动为您生成代码。Kotlin03
Intern-S2-PreviewIntern-S2-Preview,这是一款高效的350亿参数科学多模态基础模型。除了常规的参数与数据规模扩展外,Intern-S2-Preview探索了任务扩展:通过提升科学任务的难度、多样性与覆盖范围,进一步释放模型能力。Python00
skillhubopenJiuwen 生态的 Skill 托管与分发开源方案,支持自建与可选 ClawHub 兼容。Python0112
热门内容推荐
最新内容推荐
项目优选
收起
暂无描述
Dockerfile
733
4.75 K
deepin linux kernel
C
31
16
Ascend Extension for PyTorch
Python
651
797
Claude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed.
Get Started
Rust
1.25 K
153
旨在打造算法先进、性能卓越、高效敏捷、安全可靠的密码套件,通过轻量级、可剪裁的软件技术架构满足各行业不同场景的多样化要求,让密码技术应用更简单,同时探索后量子等先进算法创新实践,构建密码前沿技术底座!
C
1.1 K
611
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.01 K
1.01 K
华为昇腾面向大规模分布式训练的多模态大模型套件,支撑多模态生成、多模态理解。
Python
147
237
昇腾LLM分布式训练框架
Python
168
200
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
434
395
暂无简介
Dart
986
253