各类网站,做发型的网站,企业品牌策划,小程序开发一般采用的技术阶段 2 – 购物车#xff08;超详细版#xff09; 目标 把“加入购物车”做成 全局状态#xff0c;任何页面都能读写在本地 持久化#xff08;关闭小程序后购物车仍在#xff09;新建 购物车页#xff1a;数量增减、总价实时计算、去结算入口打 Git Tag v2.0‑cart 1. …阶段 2 – 购物车超详细版 目标 把“加入购物车”做成 全局状态任何页面都能读写在本地 持久化关闭小程序后购物车仍在新建 购物车页数量增减、总价实时计算、去结算入口打 Git Tag v2.0‑cart 1. 学到的核心技术
技术/概念关键 API/组件为什么要学全局状态App.globalData / 简易 store.js小项目先不引入第三方状态库足够用本地持久化wx.setStorageSync / wx.getStorageSync保证用户切后台、重进小程序后数据不丢UI 组件(弹出购物车) (底部结算条) (数量加减)快速完成电商式交互TabBar Badgewx.setTabBarBadge在底部“购物车”图标上显示件数 2. 项目结构新增
miniprogram/├─ store/ # 新增│ └─ cart.js├─ pages/│ ├─ index/ # 首页已存在│ └─ cart/ # 新建购物车页面3. 编写轻量级全局 Store 路径miniprogram/store/cart.js const CART_KEY CART_V1
const store {data: { items: {} },load() {this.data.items wx.getStorageSync(CART_KEY) || {}},save() {wx.setStorageSync(CART_KEY, this.data.items)},add(dish) {const { _id } dishif (this.data.items[_id]) {this.data.items[_id].count 1} else {this.data.items[_id] { ...dish, count: 1 }}this.save()},totalCount() {return Object.values(this.data.items).reduce((s, i) s i.count, 0)},totalPrice() {return Object.values(this.data.items).reduce((s, i) s i.count * i.price, 0).toFixed(2)}}
module.exports store 4. 在 app.js 中加载购物车
// miniprogram/app.js
App({onLaunch() {const cart require(./store/cart)cart.load()this.globalData { cart }}
})5. 修改首页加入购物车 更新角标 文件pages/index/index.js 只需要把之前的 onAddCart 改成
import cart from ../../store/cartonAddCart(e) {const dish e.currentTarget.dataset.dishcart.add(dish)wx.setTabBarBadge({ index: 1, text: String(cart.totalCount()) })wx.showToast({ title: 已加入购物车, icon: success })}
}提示在 app.json 的 tabBar 数组里把第二项页面路径设成 pages/cart/index这样角标才会显示在购物车图标上。 6. 新建购物车页面
6.1 组件声明 pages/cart/index.json
{navigationBarTitleText: 购物车
}6.2 页面布局 index.wxml
view classpageblock wx:for{{list}} wx:key_idview classcart-itemimage classthumb src{{item.img}} modeaspectFill /view classinfotext classname{{item.name}}/texttext classprice¥{{item.price}}/texttext classcountx {{item.count}}/text/view/view/blockview classbottom-bartext共 {{totalCount}} 件/texttext合计¥{{totalPrice}}/textbutton typeprimary bindtaponCheckout去结算/button/view
/view
6.3 页面逻辑 index.js
const cart require(../../store/cart)Page({data: {list: [],totalCount: 0,totalPrice: 0.00},onShow() {cart.load()this.refresh()},refresh() {const items Object.values(cart.data.items)const totalCount cart.totalCount()const totalPrice cart.totalPrice()this.setData({list: items,totalCount,totalPrice})},onCheckout() {if (!this.data.totalCount) {wx.showToast({ title: 购物车为空, icon: none })return}wx.navigateTo({ url: /pages/confirm/index }) // 下一阶段页}
})
6.4 简单样式 index.wxss
.page {padding: 20rpx;
}.cart-item {display: flex;background: #fff;padding: 20rpx;margin-bottom: 20rpx;border-radius: 16rpx;box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.05);
}.thumb {width: 100rpx;height: 100rpx;border-radius: 8rpx;margin-right: 20rpx;
}.info {display: flex;flex-direction: column;justify-content: space-around;
}.name {font-weight: bold;font-size: 32rpx;
}.price {color: #fa541c;
}.count {font-size: 28rpx;color: #888;
}.bottom-bar {position: fixed;bottom: 0;left: 0;width: 100%;background: #fff;padding: 20rpx;display: flex;justify-content: space-between;box-shadow: 0 -2rpx 12rpx rgba(0,0,0,0.1);
} 7. TabBar 配置示例
// app.json节选
tabBar: {list: [{ pagePath: pages/index/index, text: 菜单, iconPath: images/icons/home.png, selectedIconPath: images/icons/home-active.png },{ pagePath: pages/cart/index, text: 购物车, iconPath: images/icons/business.png, selectedIconPath: images/icons/business-active.png }]}8. 自测清单 Git Tag
首页点两道菜 → 角标显示 2进入购物车页 看得到两条记录 关闭小程序再打开 → 数据依旧存在一切通过后
git add .
git commit -m feat: shopping cart
git tag v2.0-cart
git push --tags9. 练习进阶挑战
难度练习内容⭐给 cart.js 增加 clear() 方法在购物车页提供“一键清空”。⭐⭐在首页卡片上显示当前已选数量小圆角徽标。⭐⭐⭐把 Store 升级为 Pinia 或 Remax Recoil体验响应式自动刷新。 阶段小结
你已拥有 加入购物车 → 全局状态 → 本地持久化 → 购物车 UI 的完整链路。代码量 ≈ 250 行但逻辑清晰、易维护。接下来进入 阶段 3 – 下单 云数据库把购物车内容写入 orders 集合实现真正的下单流程。
继续加油愉快编码