1. 项目背景与技术选型电商系统作为互联网时代最典型的应用场景之一其技术实现方案一直备受开发者关注。基于Vue和Spring Boot的全栈电商系统结合了前端框架的灵活交互与后端框架的高效稳定成为当前中小型电商项目的主流选择方案。这套技术栈的优势主要体现在三个方面首先Vue.js的响应式特性和组件化开发模式能够高效处理电商系统复杂的前端交互需求其次Spring Boot的自动配置和起步依赖机制大幅简化了后端服务的搭建过程最后前后端分离的架构设计使得团队协作更加清晰系统扩展性更强。在实际开发中我们通常会采用以下核心组件前端Vue 3 Vue Router Pinia Element Plus/Vant后端Spring Boot 2.7 MyBatis Plus Spring Security数据库MySQL 8.0 Redis缓存构建工具Maven/Gradle Webpack2. 系统架构设计与模块划分2.1 整体架构设计典型的电商系统采用分层架构设计主要分为表现层Vue前端应用负责用户界面展示和交互API层RESTful接口处理前后端数据交互业务逻辑层Spring Boot服务实现核心业务规则数据访问层MyBatis持久化框架操作数据库基础设施层MySQL、Redis、消息队列等前后端通过JSON格式数据进行通信采用JWT进行身份认证。这种架构保证了系统的松耦合性各层可以独立开发和部署。2.2 核心功能模块一个完整的电商系统通常包含以下功能模块前台商城系统用户认证注册、登录、找回密码商品展示分类浏览、搜索、详情购物流程购物车、结算、订单用户中心订单管理、地址管理营销功能优惠券、秒杀、拼团后台管理系统商品管理SPU/SKU管理、库存订单管理订单处理、退款用户管理会员信息、权限内容管理轮播图、文章系统设置参数配置、日志3. 前端Vue实现关键点3.1 项目初始化与配置使用Vue CLI创建项目时建议选择以下配置vue create mall-frontend关键依赖安装npm install vue-router4 pinia axios element-plus --save项目结构通常按功能模块划分src/ ├── api/ # 接口定义 ├── assets/ # 静态资源 ├── components/ # 公共组件 ├── composables/ # 组合式函数 ├── router/ # 路由配置 ├── stores/ # Pinia状态管理 ├── styles/ # 全局样式 ├── utils/ # 工具函数 └── views/ # 页面组件3.2 典型页面实现示例以商品列表页为例核心实现逻辑包括商品筛选组件template div classfilter-container el-select v-modelfilter.category placeholder分类 el-option v-foritem in categories :keyitem.id :labelitem.name :valueitem.id / /el-select el-input v-modelfilter.keyword placeholder搜索商品 / el-button typeprimary clickhandleSearch搜索/el-button /div /template script setup import { ref } from vue import { useProductStore } from /stores/product const productStore useProductStore() const filter ref({ category: , keyword: , page: 1, size: 10 }) const handleSearch async () { await productStore.fetchProducts(filter.value) } /script商品列表展示template div classproduct-list el-row :gutter20 el-col v-forproduct in products :keyproduct.id :span6 product-card :productproduct / /el-col /el-row el-pagination v-model:currentPagefilter.page :page-sizefilter.size :totaltotal current-changehandlePageChange / /div /template script setup import { storeToRefs } from pinia import { useProductStore } from /stores/product const productStore useProductStore() const { products, total } storeToRefs(productStore) const handlePageChange (page) { filter.value.page page handleSearch() } /script4. 后端Spring Boot实现关键点4.1 项目基础搭建使用Spring Initializr创建项目时需要包含以下依赖Spring WebMyBatis FrameworkMySQL DriverLombokSpring SecurityRedis关键配置示例application.ymlspring: datasource: url: jdbc:mysql://localhost:3306/mall?useSSLfalse username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver redis: host: localhost port: 6379 mybatis: mapper-locations: classpath:mapper/*.xml configuration: map-underscore-to-camel-case: true4.2 典型业务实现以商品接口为例展示分层实现Controller层RestController RequestMapping(/api/product) RequiredArgsConstructor public class ProductController { private final ProductService productService; GetMapping public ResultPageResultProductVO listProducts( RequestParam(required false) Long categoryId, RequestParam(required false) String keyword, RequestParam(defaultValue 1) Integer page, RequestParam(defaultValue 10) Integer size) { ProductQuery query new ProductQuery(categoryId, keyword, page, size); return Result.success(productService.listProducts(query)); } }Service层Service RequiredArgsConstructor public class ProductServiceImpl implements ProductService { private final ProductMapper productMapper; Override public PageResultProductVO listProducts(ProductQuery query) { PageHelper.startPage(query.getPage(), query.getSize()); ListProduct products productMapper.selectByQuery(query); PageInfoProduct pageInfo new PageInfo(products); ListProductVO productVOs products.stream() .map(this::convertToVO) .collect(Collectors.toList()); return new PageResult(pageInfo.getTotal(), productVOs); } private ProductVO convertToVO(Product product) { // 转换逻辑 } }Mapper层Mapper public interface ProductMapper { ListProduct selectByQuery(Param(query) ProductQuery query); }对应的XML映射文件mapper namespacecom.example.mall.mapper.ProductMapper select idselectByQuery resultTypeProduct SELECT * FROM product where if testquery.categoryId ! null AND category_id #{query.categoryId} /if if testquery.keyword ! null and query.keyword ! AND name LIKE CONCAT(%, #{query.keyword}, %) /if /where /select /mapper5. 前后端交互与联调5.1 API设计规范采用RESTful风格设计API接口遵循以下原则使用HTTP动词表示操作类型GET/POST/PUT/DELETE资源使用复数名词如/products状态码规范使用200成功400参数错误401未授权等统一响应格式{ code: 200, message: success, data: {...} }5.2 跨域与安全配置Spring Boot后端需要配置CORS和SecurityConfiguration EnableWebSecurity RequiredArgsConstructor public class SecurityConfig { private final JwtAuthenticationFilter jwtAuthFilter; Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .csrf().disable() .authorizeHttpRequests() .requestMatchers(/api/auth/**).permitAll() .anyRequest().authenticated() .and() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class); return http.build(); } Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source new UrlBasedCorsConfigurationSource(); CorsConfiguration config new CorsConfiguration(); config.addAllowedOrigin(*); config.addAllowedHeader(*); config.addAllowedMethod(*); source.registerCorsConfiguration(/**, config); return new CorsFilter(source); } }5.3 前端请求封装使用axios进行HTTP请求封装// src/utils/request.js import axios from axios import { useUserStore } from /stores/user const service axios.create({ baseURL: import.meta.env.VITE_API_BASE_URL, timeout: 10000 }) service.interceptors.request.use(config { const userStore useUserStore() if (userStore.token) { config.headers.Authorization Bearer ${userStore.token} } return config }) service.interceptors.response.use( response { const res response.data if (res.code ! 200) { return Promise.reject(new Error(res.message || Error)) } return res.data }, error { return Promise.reject(error) } ) export default service6. 典型业务场景实现6.1 购物车功能实现前端实现要点使用Pinia管理购物车状态// stores/cart.js export const useCartStore defineStore(cart, { state: () ({ items: [] }), actions: { async addItem(product, quantity 1) { const existing this.items.find(item item.id product.id) if (existing) { existing.quantity quantity } else { this.items.push({ ...product, quantity }) } await this.syncToServer() }, async syncToServer() { if (isAuthenticated()) { await api.updateCart(this.items) } } } })购物车页面交互template div classcart-page el-table :datacart.items el-table-column propname label商品名称 / el-table-column label单价 template #default{row} ¥{{ row.price }} /template /el-table-column el-table-column label数量 template #default{row} el-input-number v-modelrow.quantity :min1 / /template /el-table-column el-table-column label小计 template #default{row} ¥{{ (row.price * row.quantity).toFixed(2) }} /template /el-table-column /el-table div classtotal 总计¥{{ totalAmount }} /div /div /template后端实现要点购物车数据结构设计public class CartItem { private Long productId; private String productName; private BigDecimal productPrice; private Integer quantity; private String productImage; }购物车接口实现PostMapping(/cart) public ResultVoid updateCart(RequestBody ListCartItem items) { String cartKey cart: getCurrentUserId(); redisTemplate.opsForValue().set(cartKey, items); return Result.success(); } GetMapping(/cart) public ResultListCartItem getCart() { String cartKey cart: getCurrentUserId(); ListCartItem items (ListCartItem) redisTemplate.opsForValue().get(cartKey); return Result.success(items ! null ? items : Collections.emptyList()); }6.2 订单创建流程核心流程前端提交订单数据const submitOrder async () { const orderData { items: cart.items.map(item ({ productId: item.id, quantity: item.quantity, price: item.price })), shippingAddress: selectedAddress, paymentMethod: selectedPayment } try { const order await api.createOrder(orderData) router.push(/order/${order.id}) } catch (error) { ElMessage.error(error.message) } }后端订单服务Transactional public Order createOrder(OrderDTO orderDTO) { // 1. 验证库存 checkStock(orderDTO.getItems()); // 2. 创建订单主表 Order order new Order(); order.setUserId(getCurrentUserId()); order.setTotalAmount(calculateTotal(orderDTO.getItems())); orderMapper.insert(order); // 3. 创建订单明细 ListOrderItem orderItems orderDTO.getItems().stream() .map(item - createOrderItem(order.getId(), item)) .collect(Collectors.toList()); orderItemMapper.batchInsert(orderItems); // 4. 扣减库存 reduceStock(orderItems); // 5. 清空购物车 clearCart(); return order; }7. 项目部署与优化7.1 前端部署方案生产环境部署建议使用Nginx作为静态资源服务器server { listen 80; server_name mall.example.com; location / { root /var/www/mall-frontend/dist; try_files $uri $uri/ /index.html; } location /api { proxy_pass http://backend-server; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }构建优化配置vite.config.jsexport default defineConfig({ build: { rollupOptions: { output: { manualChunks(id) { if (id.includes(node_modules)) { return id.toString().split(node_modules/)[1].split(/)[0] } } } } } })7.2 后端部署方案使用Docker容器化部署FROM openjdk:17-jdk-slim ARG JAR_FILEtarget/*.jar COPY ${JAR_FILE} app.jar ENTRYPOINT [java,-jar,/app.jar]性能优化配置server: tomcat: max-threads: 200 min-spare-threads: 10 compression: enabled: true mime-types: application/json,application/xml,text/html,text/xml,text/plain spring: datasource: hikari: maximum-pool-size: 20 connection-timeout: 300008. 开发经验与避坑指南在实际开发电商系统过程中有几个关键点需要特别注意库存并发问题使用数据库乐观锁version字段或Redis分布式锁扣减库存时采用原子操作UPDATE product SET stock stock - #{quantity} WHERE id #{productId} AND stock #{quantity}订单状态管理使用状态机模式管理订单状态流转记录完整的订单操作日志设置合理的超时取消机制支付对接使用沙箱环境充分测试实现异步通知处理做好对账和异常处理机制性能优化商品详情页使用多级缓存Redis 本地缓存列表页实现分页加载静态资源使用CDN加速安全性考虑接口参数校验使用Valid注解XSS防护前端转义/后端过滤SQL注入防护使用预编译语句CSRF防护Spring Security默认启用在开发过程中建议采用渐进式开发策略先实现核心购物流程商品→购物车→订单→支付再逐步完善其他功能模块。同时要建立完善的自动化测试体系特别是对于订单、支付等核心业务逻辑。