Vue3.2商城实战:Pinia+Vant4构建完整支付闭环

发布时间:2026/10/28 17:18:16

Vue3.2商城实战:Pinia+Vant4构建完整支付闭环 简介这是一套基于 Vue3.2 全家桶搭建的移动端电商单页面应用源码面向具备一定 Vue 基础、希望深入掌握大型 SPA 工程化开发的前端学习者与开发者。项目采用 Vue3.2 Vue-Router4.x Pinia Vant4.x 技术栈完整覆盖首页门户、商品分类、搜索、购物车、订单结算、会员中心等前台模块并配套后台数据面板、商品与订单管理等场景可作为电商类项目的实战参考模板。压缩包共 58 个文件约 2.4MB以 20 个 vue 单文件组件、13 个 js 逻辑脚本为主辅以 png 界面截图、css/less 样式、html 入口及 json、svg、ico 等配置与静态资源目录按 assets、components、router、stores、views 等分层组织结构清晰。已有 84 人学习下载。读者可从中获取组件化拆分思路、Pinia 状态管理实践、路由配置方案与移动端 UI 组件用法适合对照源码理解前后端分离下的商城前端实现。1. 新蜂商城 Vue3.2 版本一套能跑通支付闭环的单页面商城源码如果你正在找一个「不是玩具」的 Vue3 商城项目来练手或做二次开发新蜂商城 Vue3.2 版本值得拆一遍。它把 Vue3.2 Vue-Router4.x Pinia Vant4.x 这套组合拳完整落到了一个单页面商城里从首页楼层、商品分类、搜索、详情、购物车到下单结算、地址管理、订单列表链路是通的不是那种只画了几个静态页面的 demo。适合两类人一类是刚学完 Vue3 组合式 API、想找个真实项目把setup、reactive、ref用熟的新手另一类是要做移动端 H5 商城、想直接拿一套现成架构改业务的老手。它解决的核心问题是——让你不用从零搭路由、状态管理和移动端组件库的胶水层直接进业务代码。2. 技术栈选型为什么是 Vue3.2 Pinia Vant4 这套组合2.1 组合式 API 与script setup的工程收益Vue3.2 最实际的变化是script setup正式稳定配合编译宏defineProps、defineEmits、defineExpose组件写法比 Options API 短一截。在这个商城里商品卡片、SKU 选择弹窗、数量步进器这类高频复用组件用script setup写出来的逻辑聚合度明显更高——同一块业务的状态、计算属性、方法挨在一起不用在data、computed、methods之间来回跳。选型上要理解一点Vue3.2 的响应式基于Proxy和 Vue2 的Object.defineProperty是两套机制。这意味着你直接给对象新增属性、用索引改数组都能被追踪到不需要Vue.set那套后悔药。但代价是reactive解构会丢响应式这个坑后面避坑章节会专门讲。2.2 Pinia 替代 Vuex 的四个理由这个项目用 Pinia 而不是 Vuex不是跟风。落到代码上有四点实际差异没有 mutations改状态直接调 action 或在组件里改 store少一层样板。购物车加减、选中状态切换这类高频操作代码量直接砍半。天然支持 TypeScript虽然这个版本以 JS 为主但 Pinia 的类型推导是内置的后续想迁 TS 不用重写 store。模块扁平化每个 store 是独立文件useCartStore()、useUserStore()按需引入不像 Vuex 要挂到根 store 的 modules 里。DevTools 时间线调试时能看到每次 action 触发前后的状态快照排查购物车金额算错这类问题很省事。2.3 Vant4 在移动端商城的适配边界Vant4 是面向 Vue3 的版本组件按需引入靠unplugin-vue-components自动完成。商城里用得最多的是van-swipe轮播、van-goods-action商品详情底部操作栏、van-submit-bar结算栏、van-stepper数量步进、van-sku规格选择。要注意 Vant4 的样式变量体系换成了 CSS 变量主题定制不再改 less 变量而是在:root覆盖--van-*。如果你从 Vant2 迁过来这一步是血泪经验改错地方样式不生效还找不到原因。2.4 环境搭建与依赖安装先把工程跑起来。Node 版本建议 16 以上Vite 对 Node 版本有要求。# 克隆项目后进入目录 cd newbee-mall-vue3-app # 安装依赖建议用 npm 或 pnpm npm install # 启动开发服务器 npm run dev # 打包生产环境 npm run build逻辑说明npm run dev走的是 Vite 开发服务器默认端口在vite.config.js里配。npm run build产出dist目录部署时把这个目录丢到静态服务器即可。参数上如果接口地址要改找.env.development和.env.production里的VITE_APP_BASE_URL别去改 axios 实例里的硬编码。提示依赖装完如果启动报Cannot find module vue多半是 Node 版本过低或 npm 缓存脏了清缓存重装比瞎改配置快。3. 路由与状态管理落地从首页到下单的完整链路3.1 Vue-Router4 的路由表设计与懒加载单页面商城的路由分两层一级是底部 Tab 对应的首页、分类、购物车、我的二级是详情、搜索、订单、地址这些。路由表用createRoutercreateWebHashHistoryH5 常用 hash 模式部署不用配服务端 rewrite。// router/index.js import { createRouter, createWebHashHistory } from vue-router const routes [ { path: /, name: Home, component: () import(/views/home/index.vue), // 懒加载首屏只加载首页 meta: { keepAlive: true } // 标记需要缓存的页面 }, { path: /goods/:id, name: GoodsDetail, component: () import(/views/goods/detail.vue) }, { path: /cart, name: Cart, component: () import(/views/cart/index.vue), meta: { keepAlive: true } } ] const router createRouter({ history: createWebHashHistory(), routes, scrollBehavior(to, from, savedPosition) { return savedPosition || { top: 0 } // 返回时恢复滚动位置 } }) export default router逻辑说明component: () import(...)是路由级代码分割每个页面单独打包首屏不会把详情页、订单页的代码一起加载。meta.keepAlive配合router-view v-slot和keep-alive使用让首页和购物车在切换时保留状态——比如你在首页滑到第三屏进详情再返回位置还在。scrollBehavior返回savedPosition是移动端体验的关键不然每次返回都跳回顶部。参数说明createWebHashHistory的 hash 模式 URL 带#好处是部署到任何静态服务器都不用额外配置如果要用 history 模式得在 Nginx 加try_files $uri $uri/ /index.html。3.2 Pinia 购物车 store 的完整实现购物车是商城状态管理最复杂的部分涉及增删改、选中、全选、金额计算。用 Pinia 的defineStore写// stores/cart.js import { defineStore } from pinia import { ref, computed } from vue export const useCartStore defineStore(cart, () { // 购物车列表每项含 goodsId、name、price、count、checked、cover const cartList ref([]) // 计算属性已选商品总价 const totalPrice computed(() { return cartList.value .filter(item item.checked) .reduce((sum, item) sum item.price * item.count, 0) .toFixed(2) }) // 计算属性已选商品件数 const checkedCount computed(() cartList.value.filter(item item.checked).reduce((s, i) s i.count, 0) ) // 加入购物车已存在则累加数量 function addToCart(goods) { const exist cartList.value.find(item item.goodsId goods.goodsId) if (exist) { exist.count goods.count } else { cartList.value.push({ ...goods, checked: true }) } } // 切换单个商品选中状态 function toggleChecked(goodsId) { const item cartList.value.find(i i.goodsId goodsId) if (item) item.checked !item.checked } // 全选/取消全选 function toggleAll(checked) { cartList.value.forEach(item { item.checked checked }) } return { cartList, totalPrice, checkedCount, addToCart, toggleChecked, toggleAll } })逻辑说明这里用的是 Pinia 的 setup 写法ref定义状态computed定义派生数据函数直接返回。totalPrice用filterreduce算已选总价注意toFixed(2)返回字符串展示没问题但如果要参与后续计算得转回数字。addToCart先查重再累加避免同一商品出现多行。参数说明goodsId是商品唯一标识checked控制是否参与结算。真实项目里购物车数据要同步到后端这里可以加一个syncToServer的 action在每次变更后调接口。3.3 商品详情页的 SKU 选择与加购详情页的核心是规格选择。Vant4 的van-sku组件能直接接但很多项目会自己写弹窗因为要对接自己的库存接口。加购流程是选规格 → 校验库存 → 调addToCart→ 提示成功。// views/goods/detail.vue 中的加购逻辑 import { useCartStore } from /stores/cart import { showToast } from vant const cartStore useCartStore() function handleAddCart() { if (!selectedSku.value) { showToast(请选择商品规格) return } if (selectedSku.value.stock 0) { showToast(该规格暂时缺货) return } cartStore.addToCart({ goodsId: goodsInfo.value.goodsId, name: goodsInfo.value.goodsName, price: selectedSku.value.price, cover: selectedSku.value.cover, count: buyCount.value }) showToast(已加入购物车) }逻辑说明先做前置校验再操作 store这是移动端交互的基本要求——用户点了没反应比报错更糟。selectedSku是当前选中的规格对象buyCount是数量步进器的值。加购成功后用showToast给反馈不要用alert。参数说明stock是库存字段真实项目里这个值应该在选规格时实时查后端而不是用列表页带过来的缓存值否则会出现「显示有货下单却失败」的翻车场景。3.4 结算页与地址管理的数据流结算页要拿三份数据购物车已选商品、默认收货地址、订单金额。地址管理用van-address-list和van-address-edit两个组件数据存 Pinia 的 user store 里。// stores/user.js import { defineStore } from pinia import { ref } from vue export const useUserStore defineStore(user, () { const addressList ref([]) const defaultAddressId ref(null) const defaultAddress computed(() addressList.value.find(a a.addressId defaultAddressId.value) ) function setDefaultAddress(id) { defaultAddressId.value id } return { addressList, defaultAddressId, defaultAddress, setDefaultAddress } })逻辑说明defaultAddress是计算属性从列表里按 id 找默认地址避免在多个组件里重复写查找逻辑。结算页直接引defaultAddress即可。setDefaultAddress在地址列表页点「设为默认」时调用。参数说明addressId是地址唯一标识。真实项目里地址增删改都要同步后端这里可以扩展成 action 里调接口再更新本地状态。4. 避坑与排查Vue3 商城开发中最容易翻车的五个点4.1 reactive 解构丢响应式现象从 store 里const { cartList } useCartStore()解构出来模板里用cartList渲染加购后页面不更新。原因reactive对象解构出来的属性是普通值脱离了 Proxy 追踪。Pinia 的 store 本质是reactive直接解构同样丢响应式。解决要么用storeToRefs包一层要么不解构、始终用store.cartList访问。计算属性和方法可以直接解构只有状态需要storeToRefs。import { storeToRefs } from pinia const cartStore useCartStore() const { cartList, totalPrice } storeToRefs(cartStore) // 状态保持响应式 const { addToCart } cartStore // 方法直接解构4.2 Vant4 样式按需引入后组件样式丢失现象van-button能渲染但没样式或者部分组件样式正常、部分不正常。原因Vant4 的按需引入靠unplugin-vue-components的VantResolver如果vite.config.js里 resolver 配错或者手动 import 了组件却没引样式就会丢样式。解决确认vite.config.js里Components({ resolvers: [VantResolver()] })配置正确且不要手动import vant/lib/index.css全量引入——两者混用会导致样式重复或冲突。4.3 路由懒加载导致的首次进入白屏现象从首页点进详情页第一次会白屏一下再显示。原因懒加载的 chunk 首次请求需要时间网络慢时白屏明显。解决给路由切换加 loading 状态或者对高频页面详情、购物车用prefetch预加载。Vite 里可以用import(/* vite-ignore */ ...)配合requestIdleCallback在空闲时预取。4.4 移动端 300ms 点击延迟与滚动穿透现象按钮点击感觉慢半拍弹窗打开后背景还能滚。原因老式移动端浏览器有 300ms 延迟等双击缩放弹窗滚动穿透是 body 没锁。解决Vant 组件默认处理了点击延迟。滚动穿透在弹窗打开时给 body 加overflow: hidden关闭时移除。Vant 的van-popup有lock-scroll属性默认开启如果自己写弹窗要手动处理。4.5 打包后接口 404 或跨域现象开发环境接口正常打包部署后请求 404 或跨域报错。原因开发环境的跨域靠 Vite 的server.proxy代理打包后代理失效请求直接打到静态服务器域名。解决生产环境要么让后端配 CORS要么在 Nginx 里配反向代理把/api转发到后端。别指望打包后 proxy 还生效这是两套机制。5. 进阶技巧用 keep-alive 缓存列表页并精准控制缓存范围列表页缓存是商城体验的分水岭。首页、分类页、购物车需要缓存详情页、订单页不需要。keep-alive的include配合组件name能精准控制但script setup下组件没有显式 name得用defineOptions声明。!-- App.vue -- router-view v-slot{ Component } keep-alive :include[Home, Cart, Category] component :isComponent / /keep-alive /router-view!-- views/home/index.vue -- script setup defineOptions({ name: Home }) // 必须和 keep-alive 的 include 对应 /script逻辑说明include数组里写的是组件 name不是路由 name。defineOptions是 Vue3.3 的宏3.2 版本可以用两个script块或者defineComponent包一层来声明 name。缓存后从首页进详情再返回首页的滚动位置、已加载的分页数据都还在不会重新请求。参数说明include支持字符串和正则写数组时注意大小写敏感。如果发现某个页面该缓存却没缓存先检查组件 name 是否和 include 里的值完全一致——这是最常见的翻车点name 拼错一个字母就静默失效。还有一个进阶用法是配合onActivated和onDeactivated生命周期。缓存页面重新激活时onActivated会触发可以在这里做数据刷新判断——比如购物车页在onActivated里重新拉一次购物车数据保证从详情页加购返回后数量是最新的。import { onActivated } from vue import { useCartStore } from /stores/cart const cartStore useCartStore() onActivated(() { // 每次进入购物车页都同步一次最新数据 cartStore.fetchCartList() })逻辑说明onActivated只在被keep-alive缓存的组件重新显示时触发首次挂载走onMounted。所以数据初始化放onMounted刷新逻辑放onActivated两者分工明确。参数说明fetchCartList是 store 里的 action负责调接口拉最新购物车。注意别在onActivated里做全量重置否则缓存就白做了——只刷新会变的数据比如库存、价格、数量。从那以后我每次做移动端商城都会先把 keep-alive 的 include 名单和组件 name 对一遍再在onActivated里只刷必要数据绝不全量重置。这套习惯帮我省了无数次「返回后数据不对」的排查时间。希望帮到你。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/10/28 17:18:16

5G NR平台OAM子系统深度解析:IOS运行时框架与SP消息驱动模型

简介:本资源是一份面向5G通信系统开发与运维工程师的OAM子系统技术解析课件,聚焦5G NR平台中运行维护管理(Operation, Administration and Maintenance)的核心实现机制。内容覆盖OAM总体架构、Makefile自动化构建框架、IOS集成操作…

2026/10/28 17:18:16

LMBA负载调制平衡放大器ADS设计:从原理到仿真全流程

简介:这份资源面向射频功率放大器方向的研究生、工程师与ADS使用者,围绕经典负载调制平衡放大器(LMBA)架构,复现Cripps团队发表于IEEE MWCL的论文《An Efficient Broadband Reconfigurable Power Amplifier Using Acti…

2026/10/28 17:18:16

PostgreSQL实战:从安装到高阶应用全解析

1. PostgreSQL实战指南:从安装到高阶应用PostgreSQL作为一款功能强大的开源关系型数据库,在企业级应用中扮演着越来越重要的角色。我使用PostgreSQL已有七年时间,从最初的简单CRUD操作到现在的复杂业务场景应用,积累了不少实战经验…

2026/10/28 19:49:09

工程师专用科技PPT模板:数据驱动+矢量图标+母版系统

简介:这是一套专为科技类内容展示设计的创意PPT模板,面向科技企业从业者、科研人员、高校师生及产品设计师,解决技术汇报中视觉表现力不足、专业感欠缺、设计耗时长等痛点。模板融合科幻元素与现代工业美学,采用沉稳灰色背景&…

2026/10/28 19:49:09

Delicious Retouch 4.5人像修图插件全攻略:磨皮美白与安装避坑

简介:一款面向摄影师与后期修图用户的PS磨皮美白扩展插件,专为Photoshop人像修饰场景设计,可快速解决肤色不均、瑕疵明显、皮肤质感不足等问题,适配专业摄影、电商修图及业余爱好者。压缩包共1221个文件,大小仅6.32MB&…

2026/10/28 19:49:09

AR试衣商业计划书模板拆解:七部分13题与二次开发

简介:商业计划书是把创业想法转化为可评审、可执行、可验证结构的基础文档,其原理是按项目背景、产品服务、用户画像、竞争分析、财务分析、团队与风险等模块组织信息,让市场调研、需求分析、商业模式和技术指标形成自洽链条。它的技术价值在…

2026/10/28 19:49:09

Python自动化竞价脚本实战:Playwright时间同步与状态机设计

“夺宝岛”这三个字,在玩拍卖竞价的人眼里基本等同于一场心跳游戏——倒计时还剩十几秒,页面上的价格每跳一次,手指就跟着抖一下。手动点加价,点慢了被别人截胡,点快了又怕自己把价格顶上去下不来。于是很多人第一反应…

2026/10/28 19:49:08

图书馆系统DFD实战:三层建模与PDF交付规范

简介:本资源是一份面向计算机专业学生及软件工程初学者的图书馆管理系统分析与设计学习材料,聚焦数据流图(DFD)建模实践,适用于课程设计、期末考试复习与系统分析能力训练。文件为单页PDF(628KB&#xff09…

2026/10/28 19:44:08

Kotlin协程作用域解析与Android开发实践

1. 为什么需要关注协程作用域?在Android开发中,内存泄漏是个老生常谈的问题。记得我刚接触Kotlin协程时,曾在一个Activity中直接启动了一个耗时协程任务,结果旋转屏幕后发现旧Activity实例竟然没有被回收。这就是典型的作用域管理…

2026/10/28 14:42:12

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/28 15:28:56

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/28 3:32:29

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/28 0:02:13

Python股票自动交易系统源码解析:从行情获取到风控的完整链路

简介:这份资源是面向高校计算机、金融相关专业毕业设计场景的完整项目源码包,主题为基于Python的股票自动交易系统,适合需要完成毕设选题、课程设计或自学金融量化交易开发的学生与开发者参考。压缩包共收录687个文件,整体约14.93…

2026/10/28 0:02:13

视酷酷信IM源码部署指南:Java 17+MySQL 8.0.33实战配置

简介:这是一套2024年亲测可部署的视酷酷信IM即时通讯系统源码,面向具备Java、OC、C#及Vue开发能力的技术人员,解决私有化即时通讯平台快速搭建与二次定制需求,尤其适用于需集成商城、保障数据主权的中小型企业或独立开发者。资源共…

2026/10/28 0:02:13

Python爬取百度迁徙数据:接口解析、批量采集与避坑指南

简介:这份资源是一个用Python爬取百度迁徙数据的脚本压缩包,面向具备Python基础、希望入门网络爬虫与数据解析的开发者,解决按日期获取全国热门城市人口迁徙数据的问题。包内共1个文件,为单个py脚本,压缩包约1KB&#…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑