vue实现树形分页
Vue 实现树形分页的方法
使用递归组件渲染树形结构
创建一个递归组件处理树形数据,通过 v-for 遍历子节点并动态渲染。组件需判断当前节点是否展开,并支持分页逻辑。
<template>
<div>
<tree-node
v-for="node in paginatedData"
:key="node.id"
:node="node"
@expand="handleExpand"
/>
<el-pagination
@current-change="handlePageChange"
:current-page="currentPage"
:page-size="pageSize"
:total="total"
/>
</div>
</template>
<script>
export default {
data() {
return {
currentPage: 1,
pageSize: 10,
flatTreeData: [] // 扁平化后的树数据
}
},
computed: {
paginatedData() {
const start = (this.currentPage - 1) * this.pageSize
return this.flatTreeData.slice(start, start + this.pageSize)
},
total() {
return this.flatTreeData.length
}
},
methods: {
flattenTree(treeData) {
// 递归扁平化树数据为列表
},
handlePageChange(page) {
this.currentPage = page
}
}
}
</script>
扁平化树形数据
分页需基于扁平化后的数据结构。通过递归遍历原始树数据,将嵌套结构转换为平面数组,同时保留层级关系信息。
flattenTree(nodes, result = [], level = 0) {
nodes.forEach(node => {
result.push({ ...node, level, isExpanded: false })
if (node.children && node.children.length > 0 && node.isExpanded) {
this.flattenTree(node.children, result, level + 1)
}
})
return result
}
动态加载与分页结合
对于大数据量树形结构,可采用懒加载方式。当用户展开节点时再加载子节点数据,同时更新分页信息。
handleExpand(node) {
node.isExpanded = !node.isExpanded
if (node.isExpanded && !node.childrenLoaded) {
fetchChildren(node.id).then(children => {
node.children = children
node.childrenLoaded = true
this.flatTreeData = this.flattenTree(this.treeData)
})
} else {
this.flatTreeData = this.flattenTree(this.treeData)
}
}
使用第三方库优化
考虑使用 el-tree 或 vue-tree-list 等现成组件,结合自定义分页逻辑:
<el-tree
:data="treeData"
:props="defaultProps"
lazy
:load="loadNode"
@node-expand="handleNodeExpand"
/>
<el-pagination
:total="visibleNodeCount"
@current-change="updateVisibleNodes"
/>
性能优化建议
- 虚拟滚动:对超大数据量使用
vue-virtual-scroller避免渲染所有节点 - 分页缓存:记住每页的展开状态,翻页时恢复
- 后端分页:复杂树形结构建议后端处理分页,返回当前页所需数据







