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

Nuxt.js实现v-for循环生成的手风琴元素独立切换问题解决方案

解决Vue手风琴单个元素独立切换的问题

你遇到的核心问题是所有问答项共享了同一个itemOpen状态变量,所以点击任何一个都会触发所有元素的状态切换。不用refs也不用封装组件,有两种简单的方法可以解决:

方法一:给每个问答项添加独立的状态属性

这种方法直接在原始的问答数据里添加一个open字段来记录当前项的展开/收起状态,简单直观:

1. 初始化状态

在获取到数据后,遍历每个分组的问答列表,给每个qa对象添加open属性(初始值可以设为false或true):

export default {
  data() {
    return {
      // 存储你的数据源
      contentData: {}
    }
  },
  mounted() {
    // 假设这里是你获取数据的逻辑(比如接口请求)
    this.contentData = /* 你的原始数据 */;
    
    // 为每个问答项初始化展开状态
    this.contentData.questions_groups.forEach(group => {
      group.questions_answers.forEach(qa => {
        qa.open = false; // 默认收起,需要默认展开就设为true
      });
    });
  },
  methods: {
    toggle(qa) {
      // 切换当前点击的qa项的状态
      qa.open = !qa.open;
    }
  }
}

2. 修改模板绑定

把模板里的itemOpen替换为当前qa对象的open属性,并在点击时传入当前qa:

<div v-for="qa, j in group.questions_answers" :key="j">
  <div class="question" @click="toggle(qa)" >
    <span v-if="qa.open" class="font-iconmoon icon-accordion-up"></span>
    <span v-else class="font-iconmoon icon-accordion-down"></span>
    <span class="q-text" v-html="qa.question"></span>
  </div>
  <div v-if="qa.open" class="answer" v-html="qa.answer"></div>
</div>

方法二:用独立对象存储状态(不修改原始数据)

如果你不想改动原始数据源,可以用一个单独的对象来记录每个问答项的状态,通过分组索引和问答项索引的组合作为键:

1. 定义状态存储对象

export default {
  data() {
    return {
      contentData: {},
      // 用对象存储每个项的状态,键格式为`分组索引-问答项索引`
      itemStates: {}
    }
  },
  methods: {
    toggle(groupIndex, qaIndex) {
      const stateKey = `${groupIndex}-${qaIndex}`;
      // 切换对应项的状态,默认初始为false
      this.itemStates[stateKey] = !this.itemStates[stateKey];
    }
  }
}

2. 修改模板绑定

在遍历分组时记录分组索引,点击时传入分组和问答项的索引:

<div v-for="(group, i) in contentData.questions_groups" :key="i">
  <h2>{{ group.group_heading }}</h2>
  <div v-for="qa, j in group.questions_answers" :key="j">
    <div class="question" @click="toggle(i, j)" >
      <span v-if="itemStates[`${i}-${j}`]" class="font-iconmoon icon-accordion-up"></span>
      <span v-else class="font-iconmoon icon-accordion-down"></span>
      <span class="q-text" v-html="qa.question"></span>
    </div>
    <div v-if="itemStates[`${i}-${j}`]" class="answer" v-html="qa.answer"></div>
  </div>
</div>

为什么这两种方法可行?

原来的代码中,所有循环项都绑定了同一个itemOpen变量,所以一个改动会影响所有项。而上面的方法给每个问答项分配了独立的状态变量,点击时只切换当前项的状态,自然就实现了独立切换。

不需要使用refs,这两种轻量的方式完全可以满足需求;封装组件虽然也能解决,但确实没必要为了这个场景增加额外的组件层级。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 23:33:15