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

Vue 实现商品加入购物车后禁用Add to Cart按钮、移除后恢复可用求助

实现方案

1. 调整store.js补充Vuex mutations

直接修改Vuex state会导致响应式异常,我们先补充规范的state修改方法:

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export const store = new Vuex.Store({
    state: {
        cart: [],
        cupcake: [{
            title: 'Cream',
            price: 12.99,
            image: 'https://images.pexels.com/photos/1055270/pexels-photo-1055270.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260',
            id: 1,
            quantity: 1
        },
        {
            title: 'Choc',
            price: 10.99,
            image: 'https://images.pexels.com/photos/1055272/pexels-photo-1055272.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260',
            id: 2,
            quantity: 1
        },
        {
            title: 'Frosting',
            price: 14.99,
            image: 'https://images.pexels.com/photos/1055271/pexels-photo-1055271.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260',
            id: 3,
            quantity: 1
        },
        {
            title: 'Berry',
            price: 9.99,
            image: 'https://images.pexels.com/photos/3081657/pexels-photo-3081657.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260',
            id: 4,
            quantity: 1
        },
        {
            title: 'Deluxe',
            price: 19.99,
            image: 'https://images.pexels.com/photos/1998634/pexels-photo-1998634.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260',
            id: 5,
            quantity: 1
        },
        {
            title: 'Oreo',
            price: 19.99,
            image: 'https://images.pexels.com/photos/783274/pexels-photo-783274.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260',
            id: 6,
            quantity: 1
        },
        ]
    },
    mutations: {
        // 商品加入购物车
        ADD_TO_CART(state, product) {
            // 避免重复添加同个商品
            if(!state.cart.find(item => item.id === product.id)) {
                state.cart.push({...product})
            }
        },
        // 移除指定商品
        REMOVE_ITEM(state, productId) {
            const index = state.cart.findIndex(item => item.id === productId)
            if(index > -1) state.cart.splice(index, 1)
        },
        // 清空购物车
        CLEAR_CART(state) {
            state.cart = []
        },
        // 增加商品数量
        INCREASE_QUANTITY(state, productId) {
            const item = state.cart.find(item => item.id === productId)
            if(item) item.quantity += 1
        },
        // 减少商品数量
        DECREASE_QUANTITY(state, productId) {
            const item = state.cart.find(item => item.id === productId)
            if(!item) return
            if(item.quantity > 1) {
                item.quantity -= 1
            } else {
                state.cart.splice(state.cart.indexOf(item), 1)
            }
        }
    }
});

2. 修改ProductCard.vue实现按钮禁用逻辑

通过computed订阅购物车状态,直接判断当前商品是否在购物车中,绑定到按钮的disabled属性即可:

<template>
  <ul
    class="
      px-32
      py-16
      grid
      row-auto
      gap-10
      grid-cols-1
      md:grid-cols-2
      xl:grid-cols-3
      2xl:grid-cols-4
    "
  >
    <li
      class="bg-white rounded-lg"
      v-for="cupcakes in cupcake"
      :key="cupcakes.id"
    >
      <img
        class="rounded-md w-screen object-cover max-h-60"
        :src="cupcakes.image"
      />
      <div class="py-2 px-8 text-gray-600">
        <span class="px-10 text-xl font-bold"> {{ cupcakes.title }}</span>
        <span class="px-10 text-xl font-bold">${{ cupcakes.price }}</span>
        <button
          class="
            bg-purple-200
            font-bold
            px-3
            mt-2
            text-xl
            py-4
            mb-4
            w-full
            rounded-md
            transition-all
            hover:bg-purple-300
            disabled:bg-gray-300 disabled:cursor-not-allowed
          "
          type="button"
          v-on:click="addToCart(cupcakes)"
          <!-- 核心禁用逻辑 -->
          :disabled="cart.some(item => item.id === cupcakes.id)"
        >
          {{ cart.some(item => item.id === cupcakes.id) ? '已加入购物车' : 'Add to Cart' }}
        </button>
      </div>
    </li>
  </ul>
</template>

<script>
export default {
  computed: {
    cupcake() {
      return this.$store.state.cupcake;
    },
    // 新增订阅购物车状态
    cart() {
      return this.$store.state.cart
    }
  },
  methods: {
    addToCart(cupcakes) {
      // 调用mutation修改state
      this.$store.commit('ADD_TO_CART', cupcakes)
    },
  },
};
</script>

3. 修正MiniCart.vue的操作逻辑

原来的删除方法参数错误导致删不掉对应商品,现在统一调用vuex mutation即可:

export default {
  computed: {
    cart() {
      return this.$store.state.cart;
    },
    total: function () {
      let total = 0;
      for (let carts of this.$store.state.cart) {
        total += carts.price * carts.quantity;
      }
      return total.toFixed(2);
    },
  },
  methods: {
    removeItem: function (carts) {
      this.$store.commit('REMOVE_ITEM', carts.id)
    },
    increase: function (carts) {
      this.$store.commit('INCREASE_QUANTITY', carts.id)
    },
    deccrease: function (carts) {
      this.$store.commit('DECREASE_QUANTITY', carts.id)
    },
    clearCart: function () {
      this.$store.commit('CLEAR_CART')
    },
  },
};

实现原理

购物车状态存在Vuex响应式state中,ProductCard组件通过computed订阅了cart的变化,只要cart发生增删操作,按钮的禁用状态会自动同步更新,不需要额外的事件监听。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 13:57:03