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
相关产品推荐
相关产品推荐

