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

Vue3组合式API:循环内产品计数器全局同步问题求助

Vue3组合式API:实现单个产品计数器独立增减

问题根源

你当前的代码中只维护了一个全局的count ref变量,所有循环渲染的产品组件都绑定了这个同一个变量。因此,无论点击哪个产品的增减按钮,都会修改这个全局值,导致所有产品的计数器同步变化。

解决方案1:给每个产品对象添加独立计数属性

直接在产品数据中加入count字段,让每个产品拥有自己的计数器,操作时仅修改当前产品的count值:

<script setup>
import { ref } from 'vue'

const products = ref([
  { id: 1, name: "Product1", count: 1 }, 
  { id: 2, name: "Product2", count: 1 },
  { id: 3, name: "Product3", count: 1 },
  { id: 4, name: "Product4", count: 1 }
])

const increment = (item) => {
  item.count++
}

const decrement = (item) => {
  // 可选:防止计数小于1
  if (item.count > 1) {
    item.count--
  }
}
</script>

<template>
  <div v-for="item in products" :key="item.id">
    <p>{{ item.name }}</p> 
    <button @click="increment(item)"> + </button>
    {{ item.count }}
    <button @click="decrement(item)"> - </button>
  </div>
</template>

解决方案2:用独立映射存储产品计数

如果不想修改原产品数据,可以用Map单独存储每个产品ID对应的计数,保持业务数据的纯净性:

<script setup>
import { ref } from 'vue'

const products = ref([
  { id: 1, name: "Product1" }, 
  { id: 2, name: "Product2" },
  { id: 3, name: "Product3" },
  { id: 4, name: "Product4" }
])

// 初始化每个产品的计数为1
const counts = ref(new Map(products.value.map(item => [item.id, 1])))

const increment = (productId) => {
  counts.value.set(productId, counts.value.get(productId) + 1)
}

const decrement = (productId) => {
  const currentCount = counts.value.get(productId)
  if (currentCount > 1) {
    counts.value.set(productId, currentCount - 1)
  }
}
</script>

<template>
  <div v-for="item in products" :key="item.id">
    <p>{{ item.name }}</p> 
    <button @click="increment(item.id)"> + </button>
    {{ counts.get(item.id) }}
    <button @click="decrement(item.id)"> - </button>
  </div>
</template>

方案说明

  • 方案1更直观,适合不需要保留原产品数据结构的场景;
  • 方案2适合原产品数据不可修改,或需要将计数状态与业务数据分离的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 12:35:28