简介:本资源是一套完整可运行的毕业设计级网上商城系统,面向计算机科学与技术、人工智能等专业的本科生及课程设计学习者,解决前后端分离架构下电商核心功能(商品展示、购物车、订单管理、用户认证)的工程化实现问题。压缩包含2034个文件,主体为1358个Markdown文档(含部署说明、Redis配置指南、Windows服务配置等技术文档)、562个JavaScript文件(Vue前端逻辑)、69个JSON配置与数据文件,整体大小117.18MB,结构清晰、模块分明,便于按层理解SpringBoot后端、Vue前端与Redis缓存协同机制。已有124人学习下载,适合毕业设计快速启动与源码级学习。资源提供已调试通过的全量源码、配套SQL脚本及详细README,涵盖Redis在Windows环境部署、服务注册、缓存策略等实操要点,可直接运行并深入分析高并发场景下的性能优化路径。
1. 项目概述与核心价值
最近在整理硬盘时,翻出了一个老项目压缩包,文件名是“《已调试》springboot+vue+redis前后端分离网上商城项目003(源码+sql).zip”。看到这个文件名,相信不少做全栈开发的朋友会心一笑,这几乎是前几年面试和练手项目的“标配”组合。Spring Boot、Vue、Redis、前后端分离,这几个词组合在一起,就勾勒出了一个典型的企业级Web应用骨架。这个项目虽然名字朴实无华,但麻雀虽小,五脏俱全,它完整地走通了一个电商平台从后端API设计、数据库建模到前端页面交互、缓存优化的全链路。对于想从单一技术栈转向全栈,或者希望深入理解现代Web应用架构的开发者来说,拆解这样一个“已调试”的项目,远比从零开始更有价值。它能让你避开许多初期的配置坑,直接聚焦于业务逻辑和架构设计的核心。
这个项目本质上是一个教学或演示级的电商系统,通常包含了用户管理、商品展示、购物车、订单、支付(模拟)等核心模块。它的价值不在于实现多么复杂的商业逻辑,而在于清晰地展示了如何将Spring Boot、Vue和Redis这三个流行的技术栈有机地整合在一起,并实践前后端分离的开发模式。通过阅读和运行这份源码,你可以快速掌握如何构建RESTful API、如何处理跨域问题、如何利用Redis提升系统性能、以及如何组织一个中等复杂度的Vue前端项目。接下来,我将带你深入这个项目的内部,逐一拆解其技术选型、架构设计、关键实现以及那些在调试过程中可能遇到的“坑”。
2. 技术栈选型与架构设计解析
2.1 为什么是Spring Boot + Vue + Redis?
这个技术组合在几年前开始风靡,至今仍有很强的生命力,其选型背后有清晰的逻辑。
后端:Spring Boot作为基石Spring Boot的核心优势在于“约定大于配置”和快速启动。对于一个网上商城项目,我们需要处理用户认证、商品CRUD、订单事务、数据校验等一系列复杂问题。Spring Boot通过自动配置和丰富的Starter依赖,几乎零配置地整合了Spring MVC(用于Web层)、Spring Data JPA/MyBatis(用于数据持久层)、Spring Security(用于安全控制)等核心模块。这允许开发者从繁琐的XML配置中解放出来,专注于业务代码。例如,项目中引入spring-boot-starter-web和spring-boot-starter-data-redis,就自动配置好了内嵌Tomcat和Redis连接池,极大地提升了开发效率。
前端:Vue.js驱动交互Vue.js以其轻量、渐进式和易于上手的特点,成为前后端分离项目中前端框架的热门选择。相比于早期的JSP或Thymeleaf等服务器端渲染技术,Vue作为纯前端框架,通过API与后端通信,实现了真正的关注点分离。前端团队可以独立开发、测试和部署,后端只需提供标准的JSON接口。在这个商城项目中,Vue负责构建所有用户界面:通过Vue Router管理页面路由(如/home,/product/:id,/cart),通过Vuex管理全局状态(如用户登录信息、购物车数据),通过Axios发起HTTP请求调用后端API。这种模式使得前端交互体验更加流畅,项目结构也更清晰。
缓存与中间件:Redis扮演多面手Redis在这个项目中绝非点缀,而是性能提升的关键。网上商城有几个典型的高并发、高读写场景:1.商品信息缓存:商品详情、分类列表等不常变化的数据,可以缓存在Redis中,避免频繁查询数据库。2.购物车实现:用户未登录时的临时购物车,或已登录用户的购物车草稿,非常适合用Redis的Hash结构存储(key:cart:userId, field:productId, value:商品数量)。3.会话存储:将Spring Session存储到Redis,可以实现分布式环境下的会话共享。4.限流与锁:利用Redis的原子操作实现简单的访问频率限制或分布式锁,防止超卖等问题。因此,引入Redis是应对电商典型场景的必然选择。
前后端分离架构的优势该架构将应用拆分为前端(Vue项目)和后端(Spring Boot项目)两个独立的部分,通过HTTP API(通常是RESTful风格)进行通信。这样做的好处显而易见:前后端技术选型可以完全解耦,并行开发;前端可以部署在Nginx等静态服务器上,后端可以集群化部署,易于扩展;API可以被多种客户端(Web、App、小程序)复用。项目中的src/main/resources/application.yml配置文件里,通常会有CORS(跨域资源共享)的配置,这就是为这种架构模式服务的。
注意:虽然这个组合经典,但技术选型永远服务于业务和团队。如果团队更熟悉React,那么Vue可以替换;如果对JVM生态不熟,后端也可以考虑Go或Node.js。这个项目的价值在于展示了分离架构的通用实现模式,而非绑定特定技术。
2.2 项目整体目录结构与模块划分
解压项目包后,我们通常会看到两个主要的目录:一个后端Spring Boot项目和一个前端Vue项目。理解它们的结构是读懂代码的第一步。
后端项目结构(Spring Boot)
e-commerce-backend/ ├── src/main/java/com/example/ecommerce/ │ ├── EcommerceApplication.java // 项目主启动类 │ ├── config/ // 配置类目录 │ │ ├── WebConfig.java // Web配置(如CORS、拦截器) │ │ ├── RedisConfig.java // Redis序列化方式配置 │ │ └── SwaggerConfig.java // API文档配置(如果集成了Swagger) │ ├── controller/ // 控制器层,接收HTTP请求 │ │ ├── UserController.java │ │ ├── ProductController.java │ │ ├── CartController.java │ │ └── OrderController.java │ ├── service/ // 业务逻辑层接口 │ │ └── impl/ // 业务逻辑层实现 │ ├── repository/ 或 mapper/ // 数据访问层(JPA叫repository,MyBatis叫mapper) │ ├── entity/ 或 model/ // 实体类,对应数据库表 │ ├── dto/ // 数据传输对象,用于接口入参出参 │ ├── vo/ // 视图对象,用于返回给前端的数据封装 │ └── utils/ // 工具类(如JWT工具、加密工具) ├── src/main/resources/ │ ├── application.yml // 主配置文件 │ ├── static/ // 静态资源(前后端不分离时用) │ └── templates/ // 模板文件(前后端不分离时用) └── pom.xml // Maven依赖管理文件关键文件解析:
application.yml: 这里配置了数据源(MySQL)、Redis连接信息、服务器端口等。一个典型的配置片段如下:
spring: datasource: url: jdbc:mysql://localhost:3306/ecommerce_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai username: root password: yourpassword driver-class-name: com.mysql.cj.jdbc.Driver redis: host: localhost port: 6379 password: # 如果没有密码则留空 database: 0 timeout: 3000ms lettuce: pool: max-active: 8 max-wait: -1ms max-idle: 8 min-idle: 0 server: port: 8080pom.xml: 定义了项目依赖。除了Spring Boot基础starter,你一定会看到spring-boot-starter-data-redis、数据库驱动(如mysql-connector-java)、可能还有spring-boot-starter-security、jjwt(用于JWT)、swagger等。
前端项目结构(Vue 2.x)
e-commerce-frontend/ ├── public/ │ └── index.html // 页面入口模板 ├── src/ │ ├── main.js // 应用入口,初始化Vue实例并加载插件 │ ├── App.vue // 根组件 │ ├── api/ // 统一封装所有后端API请求(使用axios) │ │ ├── index.js │ │ ├── user.js │ │ ├── product.js │ │ └── order.js │ ├── router/ // Vue Router路由配置 │ │ └── index.js │ ├── store/ // Vuex状态管理配置 │ │ └── index.js │ ├── views/ 或 pages/ // 页面级组件 │ │ ├── Home.vue │ │ ├── Login.vue │ │ ├── ProductList.vue │ │ ├── ProductDetail.vue │ │ ├── Cart.vue │ │ └── Order.vue │ ├── components/ // 可复用的公共组件 │ │ ├── Header.vue │ │ ├── Footer.vue │ │ └── ProductCard.vue │ ├── assets/ // 静态资源(图片、样式) │ └── utils/ // 前端工具函数 ├── .env.development // 开发环境变量(如后端API基础URL) ├── .env.production // 生产环境变量 ├── vue.config.js // Vue CLI项目配置 └── package.json // 项目依赖和脚本关键文件解析:
src/api/index.js: 这里通常会创建一个配置好的axios实例,设置基础URL、请求超时、请求/响应拦截器。拦截器特别重要,用于在请求头自动添加JWT Token,或在收到401响应时跳转到登录页。
import axios from 'axios'; const service = axios.create({ baseURL: process.env.VUE_APP_BASE_API, // 从环境变量读取 timeout: 10000 }); // 请求拦截器 service.interceptors.request.use( config => { const token = localStorage.getItem('token'); if (token) { config.headers['Authorization'] = 'Bearer ' + token; } return config; }, error => { return Promise.reject(error); } ); // 响应拦截器 service.interceptors.response.use( response => { return response.data; }, error => { if (error.response.status === 401) { // Token过期,清空本地存储并跳转登录 localStorage.clear(); router.push('/login'); } return Promise.reject(error); } ); export default service;vue.config.js: 用于覆盖Vue CLI的默认配置,比如设置开发时代理以解决跨域问题:
module.exports = { devServer: { proxy: { '/api': { target: 'http://localhost:8080', // 后端地址 changeOrigin: true, pathRewrite: { '^/api': '' } } } } };3. 核心业务模块实现细节
3.1 用户认证与授权(JWT + Spring Security)
一个商城系统,用户认证是基石。本项目很可能会采用“JWT(JSON Web Token) + Spring Security”的方案,这也是目前无状态RESTful API的主流选择。
后端实现流程:
- 登录接口 (
/api/auth/login):在AuthController中,接收用户名和密码。UserService会校验凭据。成功后,使用JJWT库生成一个JWT Token。这个Token通常包含用户ID、用户名和过期时间等信息作为Payload。
// 示例代码片段 public String login(String username, String password) { // 1. 验证用户名密码 UserDetails userDetails = userDetailsService.loadUserByUsername(username); if (!passwordEncoder.matches(password, userDetails.getPassword())) { throw new RuntimeException("密码错误"); } // 2. 生成JWT Map<String, Object> claims = new HashMap<>(); claims.put("userId", user.getId()); claims.put("username", user.getUsername()); String token = Jwts.builder() .setClaims(claims) .setSubject(username) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() + expiration)) .signWith(SignatureAlgorithm.HS512, secretKey) .compact(); // 3. 可以将token也存入Redis,实现Token黑名单或强制下线功能(可选) redisTemplate.opsForValue().set("token:" + username, token, Duration.ofSeconds(expiration/1000)); return token; }- 配置Spring Security:需要编写一个继承
WebSecurityConfigurerAdapter的配置类。核心是重写configure(HttpSecurity http)方法,定义哪些路径需要认证,哪些可以匿名访问。同时,需要添加一个自定义的JwtAuthenticationFilter,这个过滤器会在每次请求前执行,从请求头的Authorization中提取JWT Token并进行验证。 - JwtAuthenticationFilter工作流程:
- 从请求头获取Token。
- 使用相同的
secretKey解析Token,验证签名和过期时间。 - 如果Token有效,从解析出的claims中获取用户信息(如username),然后从数据库或缓存中加载完整的
UserDetails对象。 - 将
UserDetails信息存入SecurityContextHolder,这样在后续的Controller中就可以通过@AuthenticationPrincipal注解直接获取当前用户。
前端处理流程:
- 用户在登录页面提交表单,前端调用
/api/auth/login接口。 - 收到后端返回的Token后,将其存储到
localStorage或Vuex中。 - 在
axios的请求拦截器中(如上文所示),自动将Token添加到后续所有请求的Authorization头部。 - 在路由守卫(
router.beforeEach)中,检查访问的页面是否需要登录(通过路由元信息meta.requiresAuth判断),如果需要但未检测到Token,则重定向到登录页。
实操心得:JWT的
secretKey务必足够复杂且妥善保管,最好从环境变量读取。Token的过期时间(expiration)需要权衡用户体验和安全性,通常设为2-24小时。对于安全性要求极高的操作(如支付、修改密码),即使有有效Token,也应再次验证密码或短信验证码。
3.2 商品模块与Redis缓存实践
商品模块是电商的核心,尤其是商品列表和详情页,访问频率极高。直接查数据库会给DB造成巨大压力,因此必须引入缓存。
实体与API设计:
Product实体类包含id、name、description、price、stock(库存)、categoryId等字段。ProductController提供GET /api/products(分页查询列表)、GET /api/products/{id}(获取详情)、POST /api/products(后台管理-新增)等接口。
缓存策略(Cache-Aside Pattern):这是最常用的缓存模式,逻辑在应用层控制。
- 读取数据:
- 接收商品ID。
- 首先构造缓存Key,如
product:{id}。 - 尝试从Redis中获取该Key的数据。
- 如果命中缓存,直接返回。
- 如果未命中,则查询数据库。
- 将数据库查询结果序列化后存入Redis,并设置一个合理的过期时间(如30分钟)。
- 返回数据。
- 更新/删除数据:
- 先更新数据库。
- 然后,删除Redis中对应的缓存Key。这是关键!如果先删缓存再更新数据库,在并发下可能导致旧数据被重新加载到缓存(缓存击穿)。直接更新缓存值在并发写时可能产生数据不一致,所以通常采用“删缓存”策略,让下一次读请求从DB加载最新数据。
Spring Boot中的实现:可以使用Spring Cache抽象,配合Redis实现。在ProductService的方法上添加注解:
@Service public class ProductServiceImpl implements ProductService { @Cacheable(value = "product", key = "#id") // 缓存,key为product::id public Product getProductById(Long id) { return productRepository.findById(id).orElseThrow(...); } @CacheEvict(value = "product", key = "#product.id") // 删除缓存 public Product updateProduct(Product product) { // ... 更新数据库逻辑 return savedProduct; } }同时,需要在配置类RedisConfig中启用缓存并配置缓存管理器。但请注意,Spring Cache的默认序列化方式可能不是最优的,通常需要自定义配置为Jackson2JsonRedisSerializer。
注意事项:缓存穿透(查询一个不存在的数据,导致每次请求都打到DB)和缓存雪崩(大量缓存同时过期,请求全部涌向DB)是需要防范的问题。对于穿透,可以将空结果也进行短时间缓存。对于雪崩,可以给缓存过期时间加上一个随机值。
3.3 购物车模块的双重实现
购物车是电商体验的关键环节,其设计需要兼顾用户体验(未登录也能加购)和系统一致性。
1. 未登录用户购物车(前端存储)
- 实现:用户未登录时,将购物车数据存储在浏览器的
localStorage或Vuex中。数据结构可以是一个商品ID和数量的映射对象。 - 流程:用户添加商品时,前端直接更新本地存储。在购物车页面,从本地存储读取数据并展示。当用户登录时,需要有一个“合并购物车”的操作。
- 合并逻辑:登录成功后,前端将本地存储的购物车数据,通过一个API(如
POST /api/cart/merge)发送到后端。后端需要将这部分数据与已登录用户在Redis中的购物车数据进行合并(通常是数量相加)。
2. 已登录用户购物车(Redis存储)
- 数据结构选择:使用Redis的Hash结构非常合适。Key为
cart:userId,Field为商品ID(productId),Value为商品数量(quantity)。 - 核心操作:
- 添加商品:
redisTemplate.opsForHash().increment("cart:"+userId, productId, quantity); - 获取购物车:
Map<Object, Object> entries = redisTemplate.opsForHash().entries("cart:"+userId);然后根据productId去查询完整的商品信息。 - 修改数量:同样是
increment或直接put。 - 删除商品:
redisTemplate.opsForHash().delete("cart:"+userId, productId); - 清空购物车:通常在创建订单后执行,直接
redisTemplate.delete("cart:"+userId);
- 添加商品:
- 后端接口设计:
CartController提供对购物车项的增删改查接口。所有接口都需要通过JWT认证,从Token中获取当前用户的ID来操作对应的Redis Key。
前后端协作: 前端在用户登录状态变化时(登录/登出),需要切换购物车的数据源和操作API。这是一个容易出错的点,务必在状态管理(Vuex)中做好逻辑处理。
3.4 订单模块与事务管理
订单模块是电商系统中最复杂、对数据一致性要求最高的部分,涉及库存扣减、订单创建、可能的支付回调等。
下单流程:
- 预校验:前端提交订单时,传递收货地址、购物车商品ID列表等信息。后端首先需要校验:商品是否存在、库存是否充足、用户是否合法等。
- 核心事务:校验通过后,开始一个数据库事务(Spring的
@Transactional注解)。- 扣减库存:对于订单中的每一个商品,执行
UPDATE product SET stock = stock - ? WHERE id = ? AND stock >= ?。这里使用stock >= ?进行乐观锁控制,防止超卖。如果更新影响行数为0,说明库存不足,抛出异常,事务回滚。 - 创建订单主表(Order):插入一条订单记录,状态为“待支付”。
- 创建订单明细表(OrderItem):为每个商品插入一条明细记录。
- 清空购物车:从Redis中删除该用户的购物车数据。
- 扣减库存:对于订单中的每一个商品,执行
- 事务提交:以上步骤全部成功,则提交事务。任何一步失败,则整个事务回滚,库存恢复,订单不会创建。
- 后续操作:事务成功后,可以异步进行其他操作,如发送订单创建成功通知(短信/邮件)、记录日志等。这些操作不应放在事务内,以免拖长事务时间。
订单状态流转:订单通常有多个状态:待支付->已支付->已发货->已完成。还可能包含已取消、退款中等状态。在Order实体中会有一个status字段。支付回调接口(模拟或对接第三方支付)在确认收款后,会更新订单状态为“已支付”,并可能触发后续发货流程。
关于超卖问题的再讨论:仅靠数据库乐观锁在高并发下仍可能不够。更常见的做法是“库存预扣”(或叫缓存扣减)。在用户将商品加入购物车或提交订单前,先在Redis中用一个键(如stock:product:{id})进行预扣。Redis的decr操作是原子的,可以确保并发安全。预扣成功后,再进入上述数据库事务流程。如果最终订单创建失败,需要记得恢复Redis中的预扣库存。
4. 项目部署与运维考量
4.1 多环境配置与部署
一个完整的项目需要区分开发、测试、生产环境。Spring Boot和Vue都提供了便捷的多环境配置支持。
后端多环境配置:在src/main/resources/目录下,可以创建多个配置文件:
application.yml:主配置,存放通用设置。application-dev.yml:开发环境配置,覆盖主配置。可以设置本地数据库、关闭一些安全限制等。application-prod.yml:生产环境配置。配置生产数据库地址、Redis地址、更长的Token过期时间、开启日志等。 在启动应用时,通过JVM参数-Dspring.profiles.active=prod来激活指定环境的配置。
前端多环境配置:Vue CLI项目使用.env文件。
.env.development:开发环境变量,如VUE_APP_BASE_API=http://localhost:8080.env.production:生产环境变量,如VUE_APP_BASE_API=https://api.yourdomain.com在代码中通过process.env.VUE_APP_BASE_API访问。构建时,运行npm run build会自动使用生产环境变量。
部署方式:
- 后端:使用
mvn clean package打包生成一个可执行的JAR文件(内嵌Tomcat)。在生产服务器上,只需安装Java运行环境(JRE),然后通过java -jar your-app.jar --spring.profiles.active=prod即可运行。更优的做法是使用Docker容器化部署,将应用及其依赖打包成镜像,实现环境一致性。 - 前端:运行
npm run build生成静态文件(在dist目录)。将这些文件(index.html, css, js等)部署到Nginx或Apache等Web服务器上。同时,需要在Nginx中配置反向代理,将/api路径的请求转发到后端应用服务器,以解决跨域问题。
4.2 基础监控与日志排查
项目上线后,基本的监控和日志是排查问题的生命线。
日志配置:在Spring Boot的application-prod.yml中配置日志级别和输出格式。推荐使用Logback或Log4j2。
logging: level: com.example.ecommerce: DEBUG # 自己项目包下的日志级别 org.springframework.web: INFO org.hibernate: ERROR file: name: /var/log/ecommerce/app.log pattern: console: "%d{yyyy-MM-dd HH:mm:ss} - %msg%n" file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"关键位置务必打上日志:接口入口、参数校验、核心业务逻辑、异常捕获处。使用@Slf4j注解可以方便地注入日志对象。
健康检查与监控:Spring Boot Actuator提供了生产就绪的特性。在pom.xml中添加spring-boot-starter-actuator依赖,并适当配置,可以暴露/actuator/health(健康检查)、/actuator/metrics(指标)等端点。结合Prometheus和Grafana可以搭建可视化的监控面板。
Redis监控:使用redis-cli的INFO命令,或图形化工具如Redis Desktop Manager、Another Redis Desktop Manager来查看Redis的内存使用、连接数、命中率等关键指标。确保设置了合理的maxmemory策略(如allkeys-lru)防止内存溢出。
5. 常见问题排查与性能优化
5.1 开发与调试阶段常见问题
跨域(CORS)问题
- 现象:前端控制台报错:
Access-Control-Allow-Origin。 - 原因:浏览器出于安全考虑,禁止前端页面向不同域名、端口或协议的接口发起请求。
- 解决:
- 开发环境:在Vue的
vue.config.js中配置代理(上文已提及),让开发服务器转发请求。 - 生产环境:在后端Spring Boot的
WebConfig中,通过@Configuration类配置全局CORS规则。
@Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**") // 针对的路径 .allowedOrigins("https://your-frontend-domain.com") // 允许的前端域名 .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .allowCredentials(true); // 允许携带Cookie等凭证 } }; } - 开发环境:在Vue的
- 现象:前端控制台报错:
Redis连接失败或序列化错误
- 现象:启动报错
Connection refused或操作Redis时出现ClassCastException。 - 排查:
- 检查
application.yml中Redis的host、port、password是否正确。 - 确认Redis服务器是否已启动(
redis-cli ping)。 - 序列化错误通常是因为存储和读取时使用的序列化方式不一致。确保在
RedisConfig中为RedisTemplate和CacheManager配置了相同的序列化器(如Jackson2JsonRedisSerializer)。
- 检查
- 现象:启动报错
前端路由在刷新后404
- 现象:Vue项目在非首页路由下,刷新浏览器变成404。
- 原因:Vue是单页应用(SPA),路由由前端JavaScript控制。当你刷新
/cart页面时,浏览器会向服务器请求/cart这个路径的资源,但服务器(如Nginx)上并没有这个物理文件。 - 解决:需要在Nginx配置中,将所有非静态文件的请求重定向到
index.html。
location / { try_files $uri $uri/ /index.html; }
5.2 性能优化建议
数据库层面:
- 为高频查询条件建立索引,如
product表的category_id、status字段。 - 避免
SELECT *,只查询需要的字段。 - 复杂查询考虑使用数据库的查询分析工具(如MySQL的
EXPLAIN)来优化。
- 为高频查询条件建立索引,如
缓存层面:
- 对热点数据(如首页商品列表、热门商品详情)进行主动缓存或预热。
- 合理设置缓存过期时间,平衡数据实时性和缓存命中率。
- 考虑使用Redis集群或哨兵模式实现高可用,防止单点故障。
应用层面:
- 对于商品列表等接口,一定要实现分页,避免一次性拉取大量数据。
- 使用连接池(数据库连接池、Redis连接池),并合理配置池大小。
- 将一些耗时操作(如发送邮件、生成报表)异步化,可以使用Spring的
@Async注解或消息队列(如RabbitMQ)。
前端层面:
- 对图片等静态资源进行压缩,并使用CDN加速。
- 利用Vue的
v-if和v-show合理控制组件渲染,使用keep-alive缓存不活跃的组件实例。 - 对路由进行懒加载,减小初始包体积。
回看这个“已调试”的项目包,它最大的意义在于提供了一个可运行、可观察、可修改的完整范例。我建议你在本地成功运行它之后,不要止步于此。尝试去修改它:增加一个优惠券模块、实现一个简单的推荐算法、或者将部署方式从手动改为Docker Compose。在这个过程中遇到的每一个错误和解决的每一个问题,都会让你对“SpringBoot+Vue+Redis前后端分离”这套技术栈的理解更深一层。技术的价值在于解决实际问题,而这个项目正是你开始实践的第一个沙盒。
本文还有配套的精品资源,点击获取