vue实现折叠组件
实现折叠组件的基本思路
在Vue中实现折叠组件通常需要利用动态绑定和条件渲染。核心是通过控制一个布尔值状态来决定内容是否显示,并添加过渡动画提升用户体验。
基础实现方法
使用v-show或v-if控制内容显示,配合点击事件切换状态:
<template>
<div class="collapse">
<button @click="isOpen = !isOpen">Toggle</button>
<div v-show="isOpen" class="content">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
data() {
return {
isOpen: false
}
}
}
</script>
<style>
.collapse {
border: 1px solid #ddd;
border-radius: 4px;
padding: 10px;
}
.content {
margin-top: 10px;
}
</style>
添加过渡动画
使用Vue的<transition>组件实现平滑的展开/折叠效果:

<template>
<div class="collapse">
<button @click="isOpen = !isOpen">{{ isOpen ? 'Collapse' : 'Expand' }}</button>
<transition name="slide">
<div v-show="isOpen" class="content">
<slot></slot>
</div>
</transition>
</div>
</template>
<style>
.slide-enter-active, .slide-leave-active {
transition: max-height 0.3s ease;
overflow: hidden;
}
.slide-enter, .slide-leave-to {
max-height: 0;
}
.slide-enter-to, .slide-leave {
max-height: 1000px;
}
</style>
可复用组件实现
创建可配置的折叠面板组件,支持自定义标题和初始状态:
<template>
<div class="collapse-panel">
<div class="header" @click="toggle">
<slot name="header">{{ title }}</slot>
<span class="icon">{{ isOpen ? '-' : '+' }}</span>
</div>
<transition name="fade">
<div v-show="isOpen" class="body">
<slot></slot>
</div>
</transition>
</div>
</template>
<script>
export default {
props: {
title: {
type: String,
default: 'Panel'
},
isOpenByDefault: {
type: Boolean,
default: false
}
},
data() {
return {
isOpen: this.isOpenByDefault
}
},
methods: {
toggle() {
this.isOpen = !this.isOpen
}
}
}
</script>
<style>
.collapse-panel {
margin-bottom: 10px;
}
.header {
background: #f5f5f5;
padding: 10px;
cursor: pointer;
display: flex;
justify-content: space-between;
}
.body {
padding: 10px;
border: 1px solid #f5f5f5;
}
.fade-enter-active, .fade-leave-active {
transition: opacity 0.3s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
</style>
手风琴效果实现
多个折叠面板中同时只展开一个的实现方法:

<template>
<div class="accordion">
<CollapsePanel
v-for="(item, index) in items"
:key="index"
:title="item.title"
:isOpen="activeIndex === index"
@toggle="activeIndex = activeIndex === index ? null : index"
>
{{ item.content }}
</CollapsePanel>
</div>
</template>
<script>
import CollapsePanel from './CollapsePanel.vue'
export default {
components: { CollapsePanel },
data() {
return {
activeIndex: null,
items: [
{ title: 'Panel 1', content: 'Content 1' },
{ title: 'Panel 2', content: 'Content 2' },
{ title: 'Panel 3', content: 'Content 3' }
]
}
}
}
</script>
性能优化建议
对于内容较多的折叠面板,使用v-show代替v-if可以避免频繁的DOM创建/销毁。当面板初始状态为折叠且内容复杂时,配合v-if和v-show可以获得更好性能:
<div v-if="isLoaded || isOpen" v-show="isOpen" class="content">
<slot></slot>
</div>
无障碍访问支持
为折叠组件添加ARIA属性提升可访问性:
<div
role="button"
tabindex="0"
:aria-expanded="isOpen.toString()"
@click="toggle"
@keydown.enter="toggle"
>
{{ title }}
</div>
<div v-show="isOpen" role="region">
<slot></slot>
</div>






