1. 项目概述
"Spring Boot+Vue项目从零入手"是一个典型的前后端分离开发实战教程,旨在帮助开发者掌握现代Web应用开发的核心技术栈。作为一名长期从事全栈开发的工程师,我发现这种架构组合已经成为企业级应用开发的事实标准。
Spring Boot作为Java生态中最流行的后端框架,提供了快速构建生产级应用的能力;而Vue.js作为渐进式前端框架,以其轻量、灵活的特性赢得了大量开发者的青睐。两者结合既能保证后端服务的稳定性,又能提供出色的前端用户体验。
2. 技术选型解析
2.1 为什么选择Spring Boot
Spring Boot的自动配置和起步依赖特性让开发者能够快速搭建项目骨架。我在实际项目中最欣赏的几个特点:
- 内嵌服务器(Tomcat/Jetty)支持,无需部署WAR文件
- 自动化的Spring配置,减少了大量样板代码
- 丰富的starter依赖,轻松集成各种企业级组件
- 完善的生产就绪特性(健康检查、指标监控等)
2.2 为什么选择Vue.js
Vue.js作为前端框架的优势在于:
- 渐进式架构,可以从小型功能逐步扩展到完整SPA
- 响应式数据绑定,简化了DOM操作
- 组件化开发模式,提高代码复用性
- 丰富的生态系统(Vuex, Vue Router等)
- 相比React和Angular更平缓的学习曲线
3. 开发环境准备
3.1 后端环境配置
# 使用SDKMAN安装Java curl -s "https://get.sdkman.io" | bash source "$HOME/.sdkman/bin/sdkman-init.sh" sdk install java 11.0.12-open # 验证安装 java -version3.2 前端环境配置
# 安装Node.js (推荐使用nvm管理版本) curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash nvm install 16.14.2 # 安装Vue CLI npm install -g @vue/cli3.3 IDE推荐配置
- IntelliJ IDEA Ultimate (后端开发)
- VS Code (前端开发) + 必备插件:
- Vetur (Vue语法支持)
- ESLint (代码规范检查)
- Prettier (代码格式化)
4. 项目初始化
4.1 创建Spring Boot项目
使用Spring Initializr (https://start.spring.io) 生成项目骨架,推荐选择:
- Java 11
- Spring Boot 2.7.x
- 依赖项:
- Spring Web
- Lombok
- Spring Data JPA
- MySQL Driver
4.2 创建Vue项目
vue create frontend # 选择配置: # - Babel # - Router # - Vuex # - CSS Pre-processors (Sass/SCSS) # - ESLint + Prettier5. 前后端联调配置
5.1 解决跨域问题
在Spring Boot中添加配置类:
@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("http://localhost:8080") .allowedMethods("*") .allowedHeaders("*") .allowCredentials(true); } }5.2 配置代理开发服务器
在Vue项目的vue.config.js中添加:
module.exports = { devServer: { proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true, pathRewrite: { '^/api': '' } } } } }6. 典型功能实现
6.1 用户认证模块
后端实现
@RestController @RequestMapping("/api/auth") public class AuthController { @PostMapping("/login") public ResponseEntity<?> login(@RequestBody LoginRequest request) { // 实现认证逻辑 String token = jwtTokenUtil.generateToken(userDetails); return ResponseEntity.ok(new JwtResponse(token)); } }前端实现
// store/modules/auth.js const actions = { async login({ commit }, credentials) { const response = await axios.post('/api/auth/login', credentials) commit('SET_TOKEN', response.data.token) localStorage.setItem('token', response.data.token) axios.defaults.headers.common['Authorization'] = `Bearer ${response.data.token}` } }6.2 数据表格分页查询
后端分页实现
@GetMapping("/users") public Page<User> getUsers( @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "10") int size) { return userRepository.findAll(PageRequest.of(page, size)); }前端分页实现
<template> <el-table :data="tableData"> <!-- 表格列定义 --> </el-table> <el-pagination @current-change="handlePageChange" :current-page="pagination.current" :page-size="pagination.size" :total="pagination.total"> </el-pagination> </template> <script> export default { data() { return { tableData: [], pagination: { current: 1, size: 10, total: 0 } } }, methods: { async fetchData() { const res = await axios.get('/api/users', { params: { page: this.pagination.current - 1, size: this.pagination.size } }) this.tableData = res.data.content this.pagination.total = res.data.totalElements }, handlePageChange(page) { this.pagination.current = page this.fetchData() } } } </script>7. 项目优化技巧
7.1 后端性能优化
- 启用GZIP压缩:
# application.properties server.compression.enabled=true server.compression.mime-types=text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json- 使用Spring Cache抽象:
@Cacheable("products") public Product getProductById(Long id) { return productRepository.findById(id).orElse(null); }7.2 前端性能优化
- 路由懒加载:
const UserList = () => import('./views/UserList.vue')- 按需引入UI组件:
import { Button, Table, Pagination } from 'element-ui'- 使用Webpack分包策略:
// vue.config.js configureWebpack: { optimization: { splitChunks: { chunks: 'all' } } }8. 常见问题解决
8.1 跨域问题排查
- 检查后端CORS配置是否正确
- 确认前端请求URL是否正确
- 检查请求头是否包含
Origin - 使用Postman测试API是否正常工作
8.2 Vue组件不更新
- 确保响应式数据使用正确:
// 错误方式 this.someObject.property = newValue // 正确方式 this.$set(this.someObject, 'property', newValue)- 检查Vuex状态变更是否通过mutation
8.3 Spring Boot热部署失效
- 添加devtools依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency>- 启用IDE的自动构建功能
- 设置
spring.devtools.restart.enabled=true
9. 项目部署方案
9.1 后端部署
- 打包可执行JAR:
mvn clean package- 使用Docker部署:
FROM openjdk:11-jre COPY target/*.jar app.jar ENTRYPOINT ["java","-jar","/app.jar"]9.2 前端部署
- 生产环境构建:
npm run build- Nginx配置示例:
server { listen 80; server_name yourdomain.com; location / { root /path/to/dist; try_files $uri $uri/ /index.html; } location /api { proxy_pass http://backend:8080; } }10. 进阶开发建议
后端API文档化:
- 集成Swagger或SpringDoc OpenAPI
- 使用Knife4j增强UI体验
前端状态管理:
- 复杂应用使用Vuex进行状态管理
- 考虑使用Pinia作为Vuex的替代方案
微服务演进:
- 将单体应用拆分为微服务
- 使用Spring Cloud组件(Feign, Eureka等)
前端微前端架构:
- 使用Module Federation实现微前端
- 考虑qiankun框架集成
持续集成/持续部署:
- 配置GitHub Actions或Jenkins流水线
- 自动化测试和部署流程
在实际项目开发中,我通常会先建立好前后端的通信规范,定义清晰的API契约。使用OpenAPI/Swagger可以很好地解决这个问题。同时,前后端团队应该保持密切沟通,特别是在接口变更时,要及时同步更新文档和客户端代码。