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

Vue.js实现手风琴点击其他项不关闭、仅点击自身才关闭的咨询

Vue.js 多展开态手风琴菜单实现方案

问题核心原因

原有代码仅使用全局的isOpen和selected变量记录展开状态,同一时间只能记录一个展开项,因此点击其他项时会覆盖之前的展开状态,不符合允许多个项同时展开的需求。

改造方案

1. 数据层修改

将全局展开状态替换为数组,单独存储每个已展开项的唯一标识

2. 切换逻辑修改

点击时仅操作当前项的展开状态,不影响其他已展开项

3. 视图层适配

类名绑定和子菜单显示判断,都改为基于当前项自身的展开状态

完整修改后代码

Vue逻辑代码

new Vue({
  el: '#demo',
  data () {
    return {
      // 存储已展开菜单项的item_name
      openedItems: [],
      headerDesktopMenu: {
        menu: {
          menu_items: [
            {item_name:11111, childrens: [{item_name: 11}, {item_name: 12}]},
            {item_name:22222, childrens: [{item_name: 21}, {item_name: 22}]},
            {item_name:33333, childrens: [{item_name: 31}, {item_name: 32}]},
            {item_name:44444, childrens: [{item_name: 41}, {item_name: 42}]}
          ]
        }
      }
    }
  },
  methods: {
    toggleAccordion (itemName) {
      const existIndex = this.openedItems.indexOf(itemName)
      if (existIndex > -1) {
        // 已展开则移除,触发关闭
        this.openedItems.splice(existIndex, 1)
      } else {
        // 未展开则加入,触发开启
        this.openedItems.push(itemName)
      }
    },
    // 动态获取当前菜单项的样式类
    getAccordionClasses (itemName) {
      const isOpen = this.openedItems.includes(itemName)
      return {
        'is-closed': !isOpen,
        'is-primary': isOpen,
        'is-dark': !isOpen
      };
    }
  }
})

Vue.config.productionTip = false
Vue.config.devtools = false

HTML模板代码

<div id="demo">
<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(menu.item_name)"
  >
      <a class="title" @click="toggleAccordion(menu.item_name)">{{ menu.item_name }}</a>
      <ul class="level-1-wrp" v-if="menu.childrens">
          <li 
            class="level-1" 
            v-for="(submenuone, indexone) in menu.childrens" 
            :key="indexone" 
            v-if="openedItems.includes(menu.item_name)"
          >
              <a class="title">{{ submenuone.item_name }}</a>
          </li>
      </ul>
  </li>
</ul>
</div>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 13:15:03