vue实现列表展开收缩
Vue 列表展开/收缩实现方法
基础实现(v-show/v-if + 状态控制)
通过v-show或v-if控制子元素的显示隐藏,配合点击事件切换状态:
<template>
<div>
<button @click="isExpanded = !isExpanded">
{{ isExpanded ? '收起' : '展开' }}
</button>
<div v-show="isExpanded">
<!-- 列表内容 -->
<ul>
<li v-for="item in items" :key="item.id">{{ item.text }}</li>
</ul>
</div>
</div>
</template>
<script>
export default {
data() {
return {
isExpanded: false,
items: [
{ id: 1, text: '项目1' },
{ id: 2, text: '项目2' }
]
}
}
}
</script>
动画效果实现(Transition)
添加展开/收缩的动画过渡效果:

<template>
<div>
<button @click="toggle">切换</button>
<transition name="slide">
<ul v-show="isExpanded">
<li v-for="item in items" :key="item.id">{{ item.text }}</li>
</ul>
</transition>
</div>
</template>
<style>
.slide-enter-active, .slide-leave-active {
transition: max-height 0.5s ease;
max-height: 500px;
overflow: hidden;
}
.slide-enter, .slide-leave-to {
max-height: 0;
}
</style>
多级嵌套列表实现
递归组件实现多级展开/收缩:
<template>
<ul>
<li v-for="item in treeData" :key="item.id">
<div @click="toggle(item)">
{{ item.name }}
<span v-if="item.children">
[{{ item.expanded ? '-' : '+' }}]
</span>
</div>
<tree-list
v-if="item.children && item.expanded"
:tree-data="item.children"
/>
</li>
</ul>
</template>
<script>
export default {
name: 'TreeList',
props: ['treeData'],
methods: {
toggle(item) {
if (item.children) {
this.$set(item, 'expanded', !item.expanded)
}
}
}
}
</script>
性能优化建议

对于大型列表,使用虚拟滚动技术(如vue-virtual-scroller)避免渲染所有元素:
import { RecycleScroller } from 'vue-virtual-scroller'
export default {
components: { RecycleScroller },
// ...其他配置
}
常见问题解决方案
动态内容高度不确定时,使用max-height替代固定高度实现平滑动画。通过计算属性处理异步加载数据后的展开状态:
computed: {
visibleItems() {
return this.isExpanded ? this.allItems : this.allItems.slice(0, 3)
}
}






