推荐优先使用u-number-box组件实现增减;若手写按钮需阻止冒泡、限制边界、确保响应式;totalPrice用computed因有缓存机制且需防浮点误差;商品重复添加应查重合并;计算总价前须过滤已勾选商品。

直接用 v-model 绑定数量、配合 computed 实时算总价,就能跑通最基础的加减逻辑。不需要 Vuex、不依赖后端接口,纯前端响应式即可。
怎么用 u-number-box 或原生按钮实现增减
推荐优先使用 uView 的 u-number-box 组件(比手写 ± 按钮更稳):它自带防抖、边界限制(比如不能减到 0 下)、输入校验,且支持长按连发。若不用 UI 库,手写按钮要注意三点:
- 点击事件必须用
@click.stop阻止冒泡,否则可能误触父级 checkbox - 减操作要加判断:
if (item.count > 1) { item.count-- },不能让数量变成 0 或负数 - 加操作后建议调用
this.$forceUpdate()(仅 Vue2)或确保响应式数据是可追踪的引用类型(如用Vue.set更新数组项)
为什么 totalPrice 要用 computed 而不是 methods
因为购物车数量变化是高频操作(点一次 + 就触发一次),computed 有缓存机制:只要依赖的 goodsList 和每个 item.count、item.price 没变,就不会重复执行计算;而 methods 每次渲染都调用,容易卡顿。另外注意浮点误差:
- 别写
item.price * item.count—— 小数乘法会丢精度(比如0.1 * 3 === 0.30000000000000004) - 统一转分再算:
Math.round(item.price * 100) * item.count,最后除以 100 并.toFixed(2)
商品重复添加时怎么合并数量
用户反复点“加入购物车”,不能生成多条相同商品记录。关键在添加逻辑里做查重合并:
- 用
findIndex查已存在项:const idx = cartItems.findIndex(i => i.id === newGoods.id) - 存在则更新数量:
cartItems[idx].count += newGoods.count - 不存在则
push新项 - 注意:如果商品靠
name判重(比如没 ID),要小心同名不同规格商品被错误合并
最易被忽略的是「数量变更后,未勾选的商品不该计入总价」——全选/单选状态和数量是两个独立维度,计算总价前必须先过滤 goodsList.filter(i => i.checked),否则用户取消勾选了还扣钱,体验直接崩。


















