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

