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

Vue手风琴组件点击展开/折叠问题:如何仅展开被点击的分组?

问题:手风琴组件点击后展开所有分组,如何实现仅展开当前点击的分组?

我现在在做一个基于Vue的手风琴组件,用接口返回的groups对象作为数据源。目前点击分组名称可以显示/隐藏描述,但会把所有分组都展开/收起。我知道可以用groups里的open属性,但实际业务数据里没有这个字段,所以想借助Vue实例中添加的状态来实现。

我的代码示例如下:

var groups = { 
  "GROUP A": { 
    "name": "GROUP A", 
    "open": false, 
    "desc": "description 1", 
    "heading": "test", 
    "items": [ "item 1" ] 
  }
};

new Vue({ 
  el: ".vue", 
  data: { 
    groups: groups, 
    heading: "Plan Communications", 
    isExpanded: false 
  } 
})

解决方案

嗨,这个问题其实很好解决!你现在的问题出在isExpanded是一个全局的布尔值——所有分组都绑定同一个变量,所以你点任何一个分组,所有分组的展开状态都会跟着变。咱们换个思路,用一个对象来单独记录每个分组的展开状态,这样既不用修改原始业务数据,又能实现单独控制每个分组。

步骤1:修改Vue实例的data

把原来的isExpanded换成一个空对象expandedGroups,用来存储每个分组的展开状态,键就是分组的唯一标识(比如分组的name):

new Vue({ 
  el: ".vue", 
  data: { 
    groups: groups, 
    heading: "Plan Communications", 
    expandedGroups: {} // 用这个对象存每个分组的展开状态
  },
  // 后面加方法
})

步骤2:添加切换展开状态的方法

在Vue实例里加一个toggleExpand方法,接收分组名称作为参数,切换该分组在expandedGroups里的状态:

methods: {
  toggleExpand(groupName) {
    // 用$set是为了确保Vue能检测到对象属性的变化(如果键一开始不存在的话)
    this.$set(this.expandedGroups, groupName, !this.expandedGroups[groupName]);
  }
}

步骤3:修改模板绑定

假设你的模板是用v-for遍历分组的,那把点击事件和展开状态绑定改成这样:

<div class="vue">
  <!-- 遍历每个分组 -->
  <div v-for="group in groups" :key="group.name">
    <!-- 点击分组名称时调用toggleExpand,传递当前分组的name -->
    <h3 @click="toggleExpand(group.name)">{{ group.name }}</h3>
    <!-- 用expandedGroups[group.name]来控制这个分组的显示/隐藏 -->
    <div v-show="expandedGroups[group.name]">
      <p>{{ group.desc }}</p>
      <ul>
        <li v-for="item in group.items" :key="item">{{ item }}</li>
      </ul>
    </div>
  </div>
</div>

为什么这样可行?

  • expandedGroups对象里每个键对应一个分组的展开状态,互不干扰;
  • 不用修改原始的groups业务数据,完全符合你的需求;
  • 用$set是因为Vue默认无法检测到对象新增属性的变化,这样能确保状态更新后视图能同步刷新。

完整代码示例

<div class="vue">
  <div v-for="group in groups" :key="group.name">
    <h3 @click="toggleExpand(group.name)">{{ group.name }}</h3>
    <div v-show="expandedGroups[group.name]">
      <p>{{ group.desc }}</p>
      <ul>
        <li v-for="item in group.items" :key="item">{{ item }}</li>
      </ul>
    </div>
  </div>
</div>

<script>
var groups = { 
  "GROUP A": { 
    "name": "GROUP A", 
    "desc": "description 1", 
    "heading": "test", 
    "items": [ "item 1" ] 
  },
  "GROUP B": { 
    "name": "GROUP B", 
    "desc": "description 2", 
    "heading": "test 2", 
    "items": [ "item 2", "item 3" ] 
  }
};

new Vue({ 
  el: ".vue", 
  data: { 
    groups: groups, 
    heading: "Plan Communications", 
    expandedGroups: {}
  },
  methods: {
    toggleExpand(groupName) {
      this.$set(this.expandedGroups, groupName, !this.expandedGroups[groupName]);
    }
  }
})
</script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:22:20