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
相关产品推荐
相关产品推荐

