如何控制仅点击的ProductCard显示Add to cart按钮的Spinner
解决单个ProductCard加载状态独立控制的问题
问题根源
你现在用的loading是在composable里全局共享的状态,所有ProductCard都会共用同一个值,所以只要有一个卡片触发加载,所有卡片都会切换成Spinner。
方案一:子组件单独维护loading状态
最简单的方式是让每个ProductCard自己管自己的加载状态,相互独立不干扰:
修改后的子组件代码
<template> <div id="productCart"> <div> <NuxtLink :to="`/product/${item.slug}`" /> <NuxtLink v-if="item.name" :to="`/product/${item.slug}`"> <h5 id="productName" v-text="item.name" /> </NuxtLink> <Button v-if="!loading" @click="handleAddToCart" v-text="$t('labels.buy')" /> <Spinner v-else /> </div> </div> </template> <script setup> import { ref } from 'vue' const props = defineProps(['product']) const item = props.product // 每个卡片单独的loading状态,互不影响 const loading = ref(false) async function handleAddToCart() { loading.value = true try { // 调用原来composable里的addToBuyCart方法 await addToBuyCart({ product: item }) } finally { // 不管接口成功失败,都把loading重置回去 loading.value = false } } </script>
方案二:父组件统一管理加载中的产品ID
如果需要在父组件层面统一监控加载状态,可以用一个Set来记录当前正在加载的产品ID,再把状态传给对应子组件:
修改后的父组件代码
<template> <ProductCard v-for="product in products" :key="product.id" :product="product" :loading="loadingProductIds.has(product.id)" @add-to-cart="handleAddToCart(product)" /> </template> <script setup> import { ref } from 'vue' const products = ref([]) // 你的产品列表数据 const loadingProductIds = ref(new Set()) async function handleAddToCart(product) { loadingProductIds.value.add(product.id) try { await addToBuyCart({ product }) } finally { loadingProductIds.value.delete(product.id) } } </script>
修改后的子组件代码
<template> <div id="productCart"> <div> <NuxtLink :to="`/product/${item.slug}`" /> <NuxtLink v-if="item.name" :to="`/product/${item.slug}`"> <h5 id="productName" v-text="item.name" /> </NuxtLink> <Button v-if="!loading" @click="$emit('add-to-cart')" v-text="$t('labels.buy')" /> <Spinner v-else /> </div> </div> </template> <script setup> const props = defineProps(['product', 'loading']) const item = props.product defineEmits(['add-to-cart']) </script>
方案选择建议
- 方案一:实现简单,不需要父组件改动,适合不需要父组件感知加载状态的场景。
- 方案二:父组件统一管理状态,方便做全局统计或批量控制,适合需要在父层面处理加载逻辑的场景。
内容的提问来源于stack exchange,提问作者kozdro
相关产品推荐
相关产品推荐

