vue实现表格收缩展开
Vue 实现表格展开/收缩功能
核心思路
通过动态控制行数据的渲染或样式切换实现展开/收缩效果,常见方案包括:
- 使用
v-if/v-show控制子行显隐 - 利用 CSS 过渡动画增强交互
- 结合 Vue 的响应式数据管理展开状态
基础实现(v-show 方案)
模板部分
<template>
<table>
<tr v-for="item in tableData" :key="item.id">
<td>
<button @click="toggleExpand(item.id)">
{{ expandedRows.includes(item.id) ? '−' : '+' }}
</button>
{{ item.name }}
</td>
</tr>
<!-- 展开内容行 -->
<tr v-for="item in tableData"
v-show="expandedRows.includes(item.id)"
:key="`detail-${item.id}`">
<td colspan="2">{{ item.detail }}</td>
</tr>
</table>
</template>
脚本部分
<script>
export default {
data() {
return {
tableData: [
{ id: 1, name: '项目A', detail: '详细内容...' },
{ id: 2, name: '项目B', detail: '详细内容...' }
],
expandedRows: []
}
},
methods: {
toggleExpand(id) {
const index = this.expandedRows.indexOf(id);
index === -1
? this.expandedRows.push(id)
: this.expandedRows.splice(index, 1);
}
}
}
</script>
进阶方案(组件化封装)
可复用组件结构
<!-- ExpandableTable.vue -->
<template>
<table>
<tbody>
<tr v-for="row in data" :key="row.id">
<td>
<span @click="toggleRow(row)" class="toggle-icon">
{{ isExpanded(row) ? '▼' : '▶' }}
</span>
{{ row.name }}
</td>
</tr>
<tr v-if="isExpanded(row)" v-for="row in data" :key="`exp-${row.id}`">
<td class="expanded-content">
<slot name="detail" :row="row"></slot>
</td>
</tr>
</tbody>
</table>
</template>
逻辑封装
props: ['data'],
data() {
return { expandedIds: new Set() }
},
methods: {
toggleRow(row) {
this.expandedIds.has(row.id)
? this.expandedIds.delete(row.id)
: this.expandedIds.add(row.id);
},
isExpanded(row) {
return this.expandedIds.has(row.id);
}
}
样式优化技巧
CSS 过渡效果
.expanded-content {
transition: all 0.3s ease;
max-height: 0;
overflow: hidden;
}
tr.expanded .expanded-content {
max-height: 500px; /* 根据实际内容调整 */
}
表头缩进对齐
.toggle-icon {
display: inline-block;
width: 20px;
text-align: center;
cursor: pointer;
}
td {
padding-left: 10px;
border-bottom: 1px solid #eee;
}
性能优化建议
对于大数据量表格:
- 使用虚拟滚动(如
vue-virtual-scroller) - 避免深层响应式数据嵌套
- 考虑分页加载展开内容
- 使用
Object.freeze()冻结静态数据
第三方库推荐
-
Element UI
<el-table :data="tableData"> <el-table-column type="expand"> <template #default="props"> {{ props.row.detail }} </template> </el-table-column> </el-table> -
VxeTable
提供expand-config配置项和toggleRowExpansion方法 -
BootstrapVue
使用b-table的showDetails字段控制展开状态







