☰
Spring Boot+Vue前后端分离项目从0到1:创建配置与接口联调全解析
2026/10/18 3:01:44 网站建设 项目流程

说实话,看到“springboot+VUE+部署”这个标题,我的第一反应是:终于有人想把这套组合从头到尾认真捋一遍了。Spring Boot加VUE,几乎是目前国内中小型项目最主流的前后端分离技术栈,后端用Spring Boot快速提供接口,前端用VUE搭页面做交互,两者各司其职又天然互补。这个系列我打算从第一篇“新建项目”开始,一步步讲到最后的部署上线,把整个过程掰开揉碎,讲清楚每一步为什么这么做。如果你正在学习这套技术,或者刚拿到一个前后端分离的需求不知道怎么从零起步,这篇文章就是给你准备的,我会把自己平时建项目的完整过程原原本本过一遍,包括版本选择、配置思路、踩过的坑,尽量让不同基础的朋友都能跟下来。

这篇文章先集中解决一个核心问题:把项目的地基打好。很多新手在这个阶段就卡住了,要么是IDE里点来点去生成一个空壳不知道下一步干什么,要么是依赖选了一堆启动就报错,要么是前后端根本连不上。所以我会把规划、创建、配置、联调、构建整个链路走一遍,代码不多,但每一步都值得仔细看。

1. 先规划再动手:搭建前后端分离的基本盘

1.1 前后端分离到底是怎么一回事

我见过不少刚接触这套技术栈的人,对“前后端分离”的理解停留在“代码分成两个文件夹”这个层面,这其实远远不够。真正的分离,是让前端和后端各自成为一个独立工程,前端的代码只关心页面和交互,后端的代码只关心业务逻辑和数据存储,两者之间只通过固定格式的HTTP接口通信。

拿生活中的场景打个比方:前端像是餐厅的前台,负责接待客户、下单点菜、呈现菜品;后端像是后厨,负责真正做菜、管理食材库存。前台不需要知道后厨怎么切菜,后厨也不需要知道客户长什么样,双方只需要一份写清楚的菜单——也就是接口文档——就能顺畅配合。这个模式的好处非常直接:前后端可以并行开发,前端用Mock数据先做页面,后端用接口测试工具先把服务调通,最后再联调对接口,开发效率直线上升。

同时,这种架构也天然适配多端需求。同样的后端接口,既可以支撑VUE的Web页面,也可以给手机App调用,甚至以后要做小程序的时候,后端代码几乎不需要动。很多团队选择Spring Boot加VUE,不是因为它最时髦,而是因为它成熟、资料多、招人容易,出了问题网上一搜就有答案,这种可靠性对实际项目来说非常重要。

1.2 版本选型与开发环境准备清单

搞定了架构层面的思路,接下来要面对一个更现实的问题:用哪个版本?我见过太多因为版本不匹配导致的诡异问题,比如Spring Boot启动直接报错,或者Vue CLI创建项目时提示Node.js版本太低。这里直接给出一套我实测下来很省心的搭配。

后端方面,Spring Boot使用2.7.18这个版本。为什么不用最新的3.x?因为3.x基于JDK 17,对MyBatis Plus等生态的兼容性要求更高,很多老项目的依赖还没跟上。如果你是自己学习或者做一个普通的业务系统,2.7.18配合JDK 8或者JDK 11是最成熟可靠的组合。当然,如果你是新团队、新项目、愿意花时间处理兼容问题,也可以直接上Spring Boot 3.2加JDK 17,但建议先从2.7.18入手,把坑少踩几个。

前端方面,我用的是Vue 3搭配Vue CLI 5.x。Vue 3的响应式系统更高效,配合Composition API写代码也更有章法。Node.js版本建议用16.x或者18.x,太老的版本会导致Vue CLI运行异常。

组件推荐版本说明
JDK8 或 11与Spring Boot 2.7完全兼容
Spring Boot2.7.18生态成熟,资料丰富
Maven3.6.3及以上依赖管理必备
Node.js16.x 或 18.x适配Vue CLI 5
Vue CLI5.x创建Vue 3项目最方便
IDEIDEA 2022+自带Spring Initializr支持

数据库方面我默认使用MySQL 5.7或8.0,ORM框架用MyBatis Plus,它比原生MyBatis少写大量重复SQL,和Spring Boot 2.7.18的磨合也非常好。开发环境准备到这里就齐了,下面开始真正创建项目。

2. 后端工程创建:从零启动一个Spring Boot项目

2.1 基于IDEA的初始化流程

后端项目的创建方式很多,可以直接去Spring Initializr网页生成压缩包,也可以像我这样直接在IDEA里操作。打开IDEA,选择“New Project”,左侧选“Spring Initializr”,这时候IDEA会从远程模板拉取项目结构。如果你所在环境网络比较慢,也可以在网页上把包下载下来再导入,效果一样。

接下来填写几个关键参数。GroupId一般写成公司域名反写,这里用com.example这种形式就可以;ArtifactId是你的项目名,我习惯把后端项目命名为demo-backend,这样和前端项目从名字上就能区分开。Project SDK选你本机配置好的JDK版本,然后点击Next进入依赖选择页面。

依赖这里最容易贪多,我的建议是最小化原则,缺什么再加什么。第一篇文章只需要勾选Spring Web就够了,它会给你的项目加上Spring MVC能力,让你能编写和暴露HTTP接口。数据库相关的依赖后面我们实际需要操作数据库时再加,这比你一次性勾选一堆MyBatis、MySQL驱动、JPA但完全不知道怎么用要靠谱得多。生成完成后,IDEA会自动下载Maven依赖,第一次会比较慢,等右下角进度条跑完即可。

项目打开后不要急着写代码,先熟悉结构。入口在src/main/java下,有一个DemoBackendApplication.java,它带@SpringBootApplication注解,是整个项目的启动入口,双击运行这个类就能启动后端服务。src/main/resources里放配置文件和静态资源,pom.xml是整个项目的依赖清单,这些构成Spring Boot项目最基本的面貌。

2.2 把依赖和配置理顺

IDEA生成的基础工程只带了一些默认配置,我们还需要手动完善。打开pom.xml,把下面这些依赖加进去:

<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.3.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> </dependencies>

这里我直接引入了MyBatis Plus和MySQL驱动,因为做业务系统基本离不开数据库操作。MyBatis Plus默认的CRUD能力可以省掉大量单表操作SQL,它就是MyBatis的增强版,不用封装很麻烦的Mapper基础方法。如果你不想用这个框架,换成Spring Data JPA也可以,但后面的文章都会围绕MyBatis Plus展开,建议保持一致。

依赖配好后,进入src/main/resources/application.yml文件。首次创建项目时,IDEA生成的是application.properties,我习惯改成application.yml,因为YAML格式的缩进结构更直观,配置多的时候不会挤在一起:

server: port: 8080 spring: application: name: demo-backend datasource: url: jdbc:mysql://localhost:3306/demo_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai username: root password: 你的数据库密码 driver-class-name: com.mysql.cj.jdbc.Driver mybatis-plus: configuration: map-underscore-to-camel-case: true global-config: db-config: id-type: auto

端口默认8080,这个后面前端配置请求转发时要严格对应。数据库连接信息先按本机MySQL的情况填好,如果数据库还没有创建,可以先在MySQL里执行一句CREATE DATABASE demo_db DEFAULT CHARACTER SET utf8mb4;,避免后面联调时因为连不上库而报错。map-underscore-to-camel-case这个配置开启后,数据库里的下划线字段能自动映射到Java的驼峰属性,省去手动做映射的麻烦。

2.3 第一个接口:让项目先跑起来

配置完成后,写一个最简单的接口验证工程通畅。新建一个controller包,在里边创建HelloController.java:

@RestController @RequestMapping("/api/hello") public class HelloController { @GetMapping public Map<String, Object> hello() { Map<String, Object> result = new HashMap<>(); result.put("code", 200); result.put("message", "后端连接成功"); return result; } }

这段代码的作用很简单:当浏览器访问http://localhost:8080/api/hello时,后端返回一段JSON数据。用@RestController而不是@Controller,是因为这个接口直接返回数据而不是页面模板,省去了@ResponseBody的重复书写。@RequestMapping("/api/hello")定义的是接口的基础路径。

写完以后,运行项目主类,看到控制台输出“Tomcat started on port(s): 8080”就说明后端已经启动成功。这时浏览器直接访问上面的地址,能看到返回的JSON,后端工程的第一关就算过了。这个步骤虽然简单,但它验证了整条链路:项目能启动、依赖没问题、接口能访问,后端的骨架搭得没问题。

3. 前端工程创建:初始化VUE项目与开发配置

3.1 用Vue CLI生成工程骨架

后端跑通以后,开始创建前端项目。打开一个干净的文件夹,我先用npm安装Vue CLI命令行工具:

npm install -g @vue/cli

安装完成后,执行:

vue create demo-frontend

命令执行过程中,Vue CLI会询问使用哪种预设。我的选择是Vue 3预设,它包含了Vue Router和Pinia的基础配置,适合大部分中后台项目。如果你是第一次操作,不想被那么多交互问题缠住,直接选默认预设也是可以的。创建过程中如果提示你选择包管理器,选npm即可。

创建完成后几秒钟,Vue项目的基本骨架就生成好了。进入项目文件夹,启动开发服务器:

cd demo-frontend npm run serve

默认端口是8080,但这和我们的后端端口冲突了。我会在稍后的配置里把这个端口改成3000,因为前端开发服务器和后端服务跑在同一台电脑上时,端口必须区分开。启动成功后终端会显示一个本地访问地址,用浏览器打开能看到Vue自带的欢迎页面,说明前端工程也通了。

3.2 前端目录结构与关键文件说明

Vue CLI生成的前端工程目录结构非常清晰,我刚接触的时候最喜欢的就是它这种一眼能看明白的划分。src目录是所有开发代码的所在地,views放页面级组件,components放可复用组件,router放路由配置,store放状态管理,api放接口请求封装。这几个目录在后续开发中会高频使用。

入口文件src/main.js负责创建应用实例并挂载到页面,src/App.vue是根组件,所有的页面都在它内部渲染。平时我们写页面,主要就是在views里新建组件,然后在router/index.js里配置路由映射关系。每一个.vue文件都是一个单文件组件,内部由<template>、<script>、<style>三部分组成,模板写HTML结构,脚本写逻辑,样式写CSS,这种组织方式让一个页面的相关代码内聚在一个文件里,维护起来非常顺手。

刚创建项目时目录里还会有一些示例代码,比如HelloWorld.vue。我的习惯是先删掉这些示例组件,保持项目干净,然后按照自己的业务需求重新组织目录结构。干净的起点能少很多干扰。

3.3 开发环境的请求转发配置

前后端是两套独立服务,前端跑在3000端口,后端跑在8080端口。如果前端页面直接向后端接口发请求,浏览器会因为跨域限制而拦截响应。解决这个问题有一个非常方便的思路:在开发服务器里配置一条请求转发规则,让前端发起的/api请求由开发服务器统一转发到后端。

在项目根目录创建或修改vue.config.js文件:

const { defineConfig } = require('@vue/cli-service') module.exports = defineConfig({ transpileDependencies: true, devServer: { port: 3000, // 配置请求转发规则,把 /api 开头的请求转发到后端服务 proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true, pathRewrite: { '^/api': '' } } } } })

这里的target指向后端地址,pathRewrite把/api前缀去掉后再转发到后端。为什么要把前缀去掉?因为后端接口本身定义的路由是/api/hello,如果不重写路径,前端发请求到/api/api/hello就会404。如果你希望后端也统一加一层/api前缀,那pathRewrite可以删掉,但要保证后端接口路径和实际请求路径一致。

配置好以后,重启npm run serve,前端页面里发/api/hello请求时,开发服务器会自动把请求转给后端8080端口。这种转发只有当前端跑在开发服务器模式下才生效,生产环境的请求路径处理我们到部署章节再展开。

4. 前后端联调:第一次握手和跨域问题

4.1 把两个项目同时跑起来

做前后端分离开发,日常操作就是同时开两个终端窗口,一个跑后端,一个跑前端。后端在IDEA里直接运行主类,前端在终端执行npm run serve。前端启动完成后,访问http://localhost:3000就能看到页面。

验证前后端是否连通,最直接的方式是在Vue项目里发一个请求。先把axios装上:

npm install axios

然后在src/api目录下建一个统一请求模块:

import axios from 'axios' const request = axios.create({ baseURL: '/api', timeout: 10000 }) export default request

这里的baseURL设为/api,表示所有通过这个模块发出的请求都会自动加上/api前缀,再结合vue.config.js里的转发规则,最终请求会被送到http://localhost:8080。在任意一个页面组件里调用request.get('/hello'),如果能在Network面板里看到正常的200响应和“后端连接成功”的返回数据,说明前后端已经打通了。

我个人强烈建议在联调阶段就养成分离环境变量的习惯,而不是把/api这种路径硬编码在每个请求里。统一封装请求模块的好处是,将来环境地址变了,只需要改一处,所有页面的请求都会跟着更新,这个习惯越早建立越好。

4.2 跨域问题的根因与后端解法

尽管开发环境的转发配置解决了大部分问题,但还有一类跨域场景不能忽略:当没有走devServer转发,而是让浏览器直接向后端接口发起跨域请求时,后端必须允许跨域访问。程序中所谓的跨域,本质是浏览器的同源策略在起作用:浏览器默认不允许当前页面的源(协议、域名、端口)和目标接口的源不一致。

这种情况下,即使后端能正确处理请求,浏览器也会因为响应头里缺少必要的跨域许可而拦截数据。解决办法就是从后端返回的响应头里添加允许跨域的信息。最直接的办法是在接口上加@CrossOrigin注解,但接口多了以后会很繁琐,我更推荐做一次全局配置:

@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOriginPatterns("*") .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .allowedHeaders("*") .allowCredentials(true) .maxAge(3600); } }

这段配置的意思是:后端所有接口都允许跨域访问,允许的来源不做限制,允许常见的HTTP方法,同时也放行预检请求。这里有个容易踩的坑:如果设置allowedOrigins("*")同时又设置allowCredentials(true),在某些情况下会报错,因为浏览器的规范不允许带凭证的请求通配所有来源。用allowedOriginPatterns("*")替代就能避开这个问题。

需要注意的是,这个配置在开发阶段可以放宽,但到了生产环境,最好把允许的来源限定为你自己的前端域名,避免任何人从任意站点调用你的后端接口,这是上线前必须回头做的一步收紧操作。

5. 从开发走向部署:环境区分与构建准备

5.1 多环境配置思路

项目写完后要部署到服务器,一定会面临环境切换的问题。本地开发用本机数据库,测试环境用测试库,生产环境用正式库,各方面的配置都不一样。如果每次部署都手动改配置文件,既容易漏,也容易改错,正确的做法是引入多环境配置。

Spring Boot对多环境的支持做得非常成熟。在application.yml中配置一个激活标记:

spring: profiles: active: dev

然后建立对应的分环境配置:application-dev.yml专门写开发环境配置,application-prod.yml写生产环境配置。比如开发环境数据库连本地的localhost,生产环境连服务器的内网数据库地址,各自配置互不干扰。打包之后启动时,用启动参数指定使用哪套配置:

java -jar demo-backend.jar --spring.profiles.active=prod

前端这边也是同样的思路,Vue CLI读取的是项目根目录下的环境变量文件。新建.env.development和.env.production,在环境变量文件里写入各自的接口地址前缀。比如开发环境写VUE_APP_BASE_API=/api,生产环境写VUE_APP_BASE_API=https://api.example.com/api,然后在请求模块中改成baseURL: process.env.VUE_APP_BASE_API。构建前端项目时,Vue CLI会按照当前的构建模式把对应的环境变量内容编译进去。

5.2 后端打包与前端构建

完成了环境区分,就可以打包了。后端的打包命令非常固定,在项目根目录执行:

mvn clean package -DskipTests

-DskipTests跳过了测试用例执行,避免因为环境问题导致打包失败。打包完成后,在target目录下会生成一个demo-backend-0.0.1-SNAPSHOT.jar文件,这就是可以独立运行的后端交付物。之后的运行方式不需要再依赖IDEA,直接用java -jar就能启动。

前端的构建命令也类似:

npm run build

执行完成后,项目目录下会出现一个dist文件夹,里面是压缩混淆后的静态文件,包括index.html、css和js文件等。部署时,把dist目录里的内容放到静态服务器的发布目录里,比如Nginx的html目录,再用一个请求转发配置,把接口请求转给后端jar服务。这个具体的服务器配置细节,我会在部署篇里手把手地讲,这里你只需要先理解:jar包负责业务逻辑,dist静态文件负责页面展示,两者配合完成整体部署。

构建出来后一定要打开dist里的页面检查一下,确认资源加载路径是否正确。很多新手在这里踩坑:直接双击index.html打开是空白的,因为前端构建产物里的资源路径默认是绝对路径,必须由服务器环境解析。这属于正常现象,等部署篇配置好服务器发布目录就能正常访问。

6. 建项目阶段的高频问题与避坑建议

6.1 端口占用和启动异常

新手启动项目时最常见的报错就是端口被占用。后端启动日志里出现“Port 8080 was already in use”这类提示,说明你有另一个进程占用了8080端口。先找出占用进程,把它结束掉再重启项目。Windows和Mac的排查命令不太一样,但网上随手就能查到。如果你是同时启动了Vue CLI和Spring Boot,注意两个服务的端口必须不同,如果都用默认的8080,就会有一个服务起不来。

还有一种情况是改完端口后前端转发配置没同步更新。比如我把后端端口改成8081,但vue.config.js里的target还指向8080,前端转发出去之后依然找不到后端。改配置之后记得重启前端devServer,因为vue.config.js的改动不会被热更新自动加载。

6.2 版本匹配的连环坑

版本问题可以说是这个技术栈里最隐蔽的敌人。比如你现在用的是Spring Boot 3.2,然后网上找了一个旧版MyBatis Plus教程,照着配置启动,大概率会各种报错。建议完全按照我给的版本组合来搭,先把环境跑通,再考虑升级。

前端也是类似的道理。早几年很多人用Vue CLI 3,配合老的Node版本可以跑,但如果你安装了最新的Node 20,再回头用Vue CLI 3,创建项目阶段就可能报各种兼容性错误。所以如果你的Node版本很高,优先安装Vue CLI最新版本;如果你的电脑上有多个Node版本,也注意切换后再执行创建命令。

6.3 依赖下载与工程导入问题

Maven和npm第一次下载依赖是非常漫长的过程,如果你所在网络访问官方源很慢,可以换成国内公共仓库地址,这样下载速度快很多。配置Maven仓库时找到Maven的settings.xml文件,把mirror改成公共仓库地址;npm则是执行一下npm config set registry指向公共仓库。这些都是基础环境配置,配好以后你会发现创建项目的过程顺畅很多。

还有一种情况:后端项目导入IDEA后,右侧Maven面板一直报红,很多依赖找不到。多半是Maven仓库的本地缓存有问题,我通常会先执行一次mvn clean,再执行一次mvn compile,如果还不行就直接删掉本地仓库对应目录,让它重新下载。这不算优雅,但确实管用。


项目做到这里,一个空的Spring Boot后端工程和一个VUE前端工程已经稳稳地立起来了,两边能对话,环境能区分,构建也能跑通。我自己的体会是,建项目阶段其实最考验耐心,版本、端口、路径、仓库这些看似琐碎的配置,任何一个出错都会让后面的开发变得很别扭。所以这个阶段慢一点、细一点,反而是最值得花时间的地方。这个系列下一篇文章我会沿着这个骨架继续往里填充真实的业务代码,包括登录、鉴权、增删改查,再往后就是部署篇。先把这个地基打好,后面盖楼就快了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询