vue实现多级表格
实现多级表格的基本思路
在Vue中实现多级表格通常需要递归组件或动态渲染嵌套数据结构。核心是通过嵌套的<table>或<div>模拟表格结构,结合组件的递归调用或v-for动态渲染子级数据。
使用递归组件实现
定义一个递归组件,通过props接收层级数据,组件内部判断是否有子级数据并递归调用自身:
<template>
<table>
<thead>
<tr>
<th v-for="col in columns" :key="col.key">{{ col.title }}</th>
</tr>
</thead>
<tbody>
<tree-table-row
v-for="item in data"
:key="item.id"
:item="item"
:columns="columns"
/>
</tbody>
</table>
</template>
<script>
export default {
name: 'TreeTable',
props: ['data', 'columns'],
components: {
TreeTableRow: {
name: 'TreeTableRow',
props: ['item', 'columns'],
template: `
<template>
<tr>
<td v-for="col in columns" :key="col.key">{{ item[col.key] }}</td>
</tr>
<tr v-if="item.children && item.children.length">
<td :colspan="columns.length">
<tree-table-row
v-for="child in item.children"
:key="child.id"
:item="child"
:columns="columns"
/>
</td>
</tr>
</template>
`
}
}
}
</script>
使用第三方库
若需复杂功能(如展开折叠、拖拽排序),推荐使用现成库:
- VxeTable:支持树形表格、虚拟滚动等高级功能。
- Element UI:
el-table结合row-key和tree-props实现树形表格。
安装VxeTable示例:
npm install xe-utils vxe-table
使用示例:
<template>
<vxe-table
:data="tableData"
:tree-config="{ children: 'children' }"
>
<vxe-column field="name" title="Name" tree-node></vxe-column>
<vxe-column field="size" title="Size"></vxe-column>
</vxe-table>
</template>
<script>
import { VxeTable, VxeColumn } from 'vxe-table'
export default {
components: { VxeTable, VxeColumn },
data() {
return {
tableData: [
{ id: 1, name: 'Folder A', children: [
{ id: 2, name: 'File A1', size: '1MB' }
]}
]
}
}
}
</script>
动态加载子节点
对于大数据量,可通过懒加载优化性能。监听展开事件动态加载数据:
methods: {
loadChildren({ row }) {
return axios.get(`/api/children?id=${row.id}`).then(res => {
row.children = res.data
})
}
}
在VxeTable中配置:
<vxe-table
:tree-config="{ lazy: true, loadMethod: loadChildren }"
></vxe-table>
样式优化技巧
- 使用CSS控制缩进体现层级:
.tree-node--level-2 { padding-left: 20px; } .tree-node--level-3 { padding-left: 40px; } - 通过插槽自定义展开图标:
<vxe-column field="name" title="Name"> <template #default="{ row }"> <span class="tree-expand" @click="toggleExpand(row)"> <i v-if="row.children" :class="row.expanded ? 'icon-collapse' : 'icon-expand'"></i> {{ row.name }} </span> </template> </vxe-column>







