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

Vue3:解决v-for循环内按钮点击单独切换类名的问题

Vue3 实现列表项独立切换显示/隐藏

方案一:给列表项添加独立状态(修改原数组)

如果允许修改items数组结构,直接给每个元素加isOpen属性控制状态:

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

// 示例items数组
const items = ref([
  { id: 1, details: '<p>文本内容1</p>', isOpen: false },
  { id: 2, details: '<p>文本内容2</p>', isOpen: false },
  // 更多项...
]);

const toggleAccordion = (item) => {
  item.isOpen = !item.isOpen;
};
</script>

<template>
  <div>
    <div v-for="item in items" :key="item.id">
      <div class="my-class" :class="{ 'is-open': item.isOpen }" v-html="item.details"></div>
      <button @click="() => toggleAccordion(item)">Toggle text</button>
    </div>
  </div>
</template>

方案二:用独立状态集合(不修改原数组)

不想改动原items的话,用ref对象单独记录每个项的激活状态:

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

const items = ref([
  { id: 1, details: '<p>文本内容1</p>' },
  { id: 2, details: '<p>文本内容2</p>' },
  // 更多项...
]);

// 用对象存每个item的激活状态,键为item的id
const activeStates = ref({});

const toggleAccordion = (itemId) => {
  // 无状态时默认设为false,再取反
  activeStates.value[itemId] = !activeStates.value[itemId];
};
</script>

<template>
  <div>
    <div v-for="item in items" :key="item.id">
      <div class="my-class" :class="{ 'is-open': activeStates[item.id] }" v-html="item.details"></div>
      <button @click="() => toggleAccordion(item.id)">Toggle text</button>
    </div>
  </div>
</template>

你之前代码的问题分析

  1. 初始代码(切换所有项)
    用了单个ref(false)的isActive变量,所有列表项共享同一个状态,点击按钮自然会全量切换。

  2. 尝试索引的报错代码
    isActive是单个布尔值的ref,不是数组,isActive[i]返回undefined,访问.value就会抛出Cannot read properties of undefined (reading 'value')错误。

  3. 无报错但类名不生效的代码
    单个ref的响应式依赖是它的.value属性,直接给isActive(ref对象)加索引属性不属于Vue的响应式更新逻辑,状态变化不会触发视图更新,类名也就不生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 04:42:49