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>
你之前代码的问题分析
初始代码(切换所有项)
用了单个ref(false)的isActive变量,所有列表项共享同一个状态,点击按钮自然会全量切换。尝试索引的报错代码
isActive是单个布尔值的ref,不是数组,isActive[i]返回undefined,访问.value就会抛出Cannot read properties of undefined (reading 'value')错误。无报错但类名不生效的代码
单个ref的响应式依赖是它的.value属性,直接给isActive(ref对象)加索引属性不属于Vue的响应式更新逻辑,状态变化不会触发视图更新,类名也就不生效。
内容的提问来源于stack exchange,提问作者Kim Andersen
相关产品推荐
相关产品推荐

