vue 实现口风琴
实现口风琴效果的方法
使用Vue实现口风琴(Accordion)效果可以通过动态绑定v-for和v-show或v-if来控制内容的展开与折叠。以下是两种常见的实现方式:

基础实现(使用v-show)
通过v-show控制每个项目的展开状态,点击时切换当前项的isOpen属性。

<template>
<div class="accordion">
<div
v-for="(item, index) in items"
:key="index"
class="accordion-item"
>
<div
class="accordion-header"
@click="toggleItem(index)"
>
{{ item.title }}
</div>
<div
class="accordion-content"
v-show="item.isOpen"
>
{{ item.content }}
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ title: '标题1', content: '内容1', isOpen: false },
{ title: '标题2', content: '内容2', isOpen: false },
{ title: '标题3', content: '内容3', isOpen: false }
]
};
},
methods: {
toggleItem(index) {
this.items[index].isOpen = !this.items[index].isOpen;
}
}
};
</script>
<style>
.accordion-item {
border: 1px solid #ddd;
margin-bottom: 5px;
}
.accordion-header {
padding: 10px;
background: #f5f5f5;
cursor: pointer;
}
.accordion-content {
padding: 10px;
}
</style>
进阶实现(仅展开一项)
通过维护一个activeIndex变量,确保每次仅有一项展开,其他项自动折叠。
<template>
<div class="accordion">
<div
v-for="(item, index) in items"
:key="index"
class="accordion-item"
>
<div
class="accordion-header"
@click="setActiveIndex(index)"
>
{{ item.title }}
</div>
<div
class="accordion-content"
v-show="activeIndex === index"
>
{{ item.content }}
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
activeIndex: null,
items: [
{ title: '标题1', content: '内容1' },
{ title: '标题2', content: '内容2' },
{ title: '标题3', content: '内容3' }
]
};
},
methods: {
setActiveIndex(index) {
this.activeIndex = this.activeIndex === index ? null : index;
}
}
};
</script>
使用过渡动画
通过Vue的<transition>组件为展开/折叠添加平滑动画效果。
<template>
<div class="accordion">
<div
v-for="(item, index) in items"
:key="index"
class="accordion-item"
>
<div
class="accordion-header"
@click="setActiveIndex(index)"
>
{{ item.title }}
</div>
<transition name="fade">
<div
class="accordion-content"
v-show="activeIndex === index"
>
{{ item.content }}
</div>
</transition>
</div>
</div>
</template>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity 0.3s, max-height 0.3s;
max-height: 500px;
overflow: hidden;
}
.fade-enter, .fade-leave-to {
opacity: 0;
max-height: 0;
}
</style>
关键点说明
- 数据驱动:通过修改
isOpen或activeIndex触发视图更新。 - 性能优化:
v-show通过CSS控制显示/隐藏,适合频繁切换的场景;v-if会销毁/重建DOM,适合初始渲染成本高的内容。 - 扩展性:可通过插槽(Slot)支持自定义标题和内容模板。






