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

Vue.js手风琴Accordion在v-for循环中失效:点击任意项全部展开

问题原因

所有循环生成的菜单项共用了同一个全局isOpen状态,修改该状态会同步影响所有菜单项的展开/收起状态,因此点击任意一项所有项都会同步响应。

修复方案

改用存储当前展开项的索引来控制对应项的状态,修改后代码如下:

模板部分

<template>
<ul class="level-0-wrp" v-if="headerDesktopMenu.menu.menu_items">
    <li 
        class="level-0" 
        v-for="(menu, index) in headerDesktopMenu.menu.menu_items" 
        :key="index" 
        :class="getAccordionClasses(index)"
    >
        <a class="title" @click="toggleAccordion(index)">{{ menu.item_name }}</a>
        <ul class="level-1-wrp" v-if="menu.childrens && openIndex === index">
            <li 
                class="level-1" 
                v-for="(submenuone, indexone) in menu.childrens" 
                :key="indexone"
            >
                <a class="title">{{ submenuone.item_name }}</a>
            </li>
        </ul>
    </li>
</ul>
</template>

逻辑部分

<script>
export default {
    data () {
        return {
            // 存储当前展开的菜单项索引,初始为-1表示全部关闭
            openIndex: -1
        }
    },
    methods: {
        toggleAccordion (index) {
            // 如果点击的是当前已展开的项则收起,否则展开点击的项
            this.openIndex = this.openIndex === index ? -1 : index
        },
        getAccordionClasses(index) {
            const isCurrentOpen = this.openIndex === index
            return {
                'is-closed': !isCurrentOpen,
                'is-primary': isCurrentOpen,
                'is-dark': !isCurrentOpen
            }
        }
    }
}
</script>

如果需要支持同时展开多个菜单项,可改用数组存储已展开的索引:

data () {
  return {
    openIndexList: []
  }
},
methods: {
  toggleAccordion(index) {
    if (this.openIndexList.includes(index)) {
      this.openIndexList = this.openIndexList.filter(i => i !== index)
    } else {
      this.openIndexList.push(index)
    }
  },
  getAccordionClasses(index) {
    const isCurrentOpen = this.openIndexList.includes(index)
    return {
      'is-closed': !isCurrentOpen,
      'is-primary': isCurrentOpen,
      'is-dark': !isCurrentOpen
    }
  }
}

对应模板内子菜单的显隐判断改为v-if="menu.childrens && openIndexList.includes(index)"即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 03:27:02