You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3购物车:实现无重复添加及商品数量增减功能问题

Vue3 + Pinia 购物车问题修复方案

核心问题与修复步骤

1. 解决重复添加商品&数量不递增问题

问题根源:

  • findIndex使用对象引用比较(x === item),而非唯一标识id匹配,导致无法识别购物车内已存在的商品
  • 索引判断错误(cartItemIndex >= 1),数组索引从0开始,应改为>= 0
  • 修改了原商品数据的quantity,而非购物车内的商品项

修改Pinia Store(counter.js):

import { defineStore } from "pinia";

export const useCounterStore = defineStore("counter", {
  state: () => ({
    cart: [],
  }),
  actions: {
    addToCart(item) {
      // 通过id匹配购物车内已存在的商品
      const existingItem = this.cart.find(x => x.id === item.id);
      
      if (existingItem) {
        // 递增购物车内商品的数量
        existingItem.quantity++;
      } else {
        // 克隆商品对象,避免修改原数据源
        this.cart.push({ ...item });
      }
    },
    removeFromCart(item) {
      // 同样通过id查找待删除商品
      const cartItemIndex = this.cart.findIndex(x => x.id === item.id);
      
      if (cartItemIndex >= 0) {
        this.cart.splice(cartItemIndex, 1);
        console.log("Removed from cart");
      }
    },
    // 新增:递增指定商品数量
    increaseQuantity(item) {
      const targetItem = this.cart.find(x => x.id === item.id);
      if (targetItem) targetItem.quantity++;
    },
    // 新增:递减指定商品数量(至少保留1件)
    decreaseQuantity(item) {
      const targetItem = this.cart.find(x => x.id === item.id);
      if (targetItem && targetItem.quantity > 1) {
        targetItem.quantity--;
      }
    }
  },
});

2. 升级购物车组件(cart.vue)

添加数量增减按钮,修复总价计算逻辑,修正循环key:

<template>
  <div class="cart">
    <h1>Cart</h1>
    <div class="cartitems" v-for="item in storeCounter.cart" :key="item.id">
      {{ item.name }} {{ item.price }}$ x {{ item.quantity }}
      <button @click="storeCounter.decreaseQuantity(item)">-</button>
      <button @click="storeCounter.increaseQuantity(item)">+</button>
      <button @click="storeCounter.removeFromCart(item)">X</button>
    </div>
    <h4>Total Price: {{ cartSum }}$</h4>
  </div>
</template>

<script setup>
import { useCounterStore } from "../stores/counter";
import { computed } from "vue";

const storeCounter = useCounterStore();

// 修正总价计算:单价 × 数量 累加
const cartSum = computed(() => {
  return storeCounter.cart.reduce((total, item) => {
    return total + item.price * item.quantity;
  }, 0);
});
</script>

3. 优化商品列表组件(shop.vue)

确保购物车数量统计正确:

<template>
  <div>
    <h1>Shop</h1>
    Items in cart: <CartLength :count="totalItems">{{ totalItems }}</CartLength>
    <div v-for="item in Products" :key="item.id">
      {{ item.name }} {{ item.price }}$
      <button @click="storeCounter.addToCart(item)">Add to Cart</button>
    </div>
  </div>
</template>

<script setup>
import { useCounterStore } from "../stores/counter";
import { computed } from "vue";

const storeCounter = useCounterStore();

// 计算购物车总商品数量(累加各商品的quantity)
const totalItems = computed(() => {
  return storeCounter.cart.reduce((sum, item) => sum + item.quantity, 0);
});
</script>

内容的提问来源于stack exchange,提问作者samirkiki542

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 19:34:59