vue实现树形分页
Vue实现树形分页的方法
使用递归组件构建树形结构
在Vue中可以通过递归组件实现树形结构。定义一个组件,该组件能够调用自身来渲染子节点。结合分页逻辑,可以在每次渲染时只展示当前页的数据。
<template>
<div>
<tree-node
v-for="node in paginatedData"
:key="node.id"
:node="node"
/>
<pagination
:total="totalNodes"
:current-page="currentPage"
@page-change="handlePageChange"
/>
</div>
</template>
<script>
export default {
data() {
return {
currentPage: 1,
pageSize: 10,
treeData: [] // 完整的树形数据
}
},
computed: {
// 扁平化树形数据用于分页
flattenedData() {
const flatten = (nodes) => {
return nodes.reduce((acc, node) => {
acc.push(node)
if (node.children) {
acc.push(...flatten(node.children))
}
return acc
}, [])
}
return flatten(this.treeData)
},
// 分页后的数据
paginatedData() {
const start = (this.currentPage - 1) * this.pageSize
const end = start + this.pageSize
return this.flattenedData.slice(start, end)
},
totalNodes() {
return this.flattenedData.length
}
},
methods: {
handlePageChange(page) {
this.currentPage = page
}
}
}
</script>
按层级分页的实现
如果需要保持树形结构的层级关系进行分页,可以采用层级分页策略。这种方式会在每一层级单独进行分页。
<template>
<div>
<div v-for="node in currentLevelNodes" :key="node.id">
{{ node.name }}
<button @click="loadChildren(node)">展开</button>
<tree-page
v-if="node.children && node.expanded"
:nodes="node.children"
:level="level + 1"
/>
</div>
<pagination
v-if="level === 0"
:total="totalTopLevelNodes"
:current-page="currentPage"
@page-change="handlePageChange"
/>
</div>
</template>
<script>
export default {
name: 'TreePage',
props: {
nodes: Array,
level: {
type: Number,
default: 0
}
},
data() {
return {
currentPage: 1,
pageSize: 5
}
},
computed: {
currentLevelNodes() {
const start = (this.currentPage - 1) * this.pageSize
const end = start + this.pageSize
return this.nodes.slice(start, end)
},
totalTopLevelNodes() {
return this.level === 0 ? this.nodes.length : 0
}
},
methods: {
handlePageChange(page) {
this.currentPage = page
},
loadChildren(node) {
this.$set(node, 'expanded', !node.expanded)
}
}
}
</script>
使用第三方库
对于复杂的树形分页需求,可以考虑使用现成的Vue树形组件库,如vue-treeselect或element-ui的树形组件,结合自定义分页逻辑实现。
import { ElTree, ElPagination } from 'element-plus'
export default {
components: {
ElTree,
ElPagination
},
data() {
return {
treeData: [],
currentPage: 1,
pageSize: 10,
defaultProps: {
children: 'children',
label: 'label'
}
}
},
methods: {
async fetchPaginatedTree() {
const res = await api.getTreeData({
page: this.currentPage,
size: this.pageSize
})
this.treeData = res.data
}
},
mounted() {
this.fetchPaginatedTree()
}
}
后端分页与前端展示
对于大数据量的树形结构,建议在后端实现分页逻辑,前端只负责展示当前页的数据。这种方式能显著提高性能。
export default {
methods: {
async loadNode(node, resolve) {
if (node.level === 0) {
// 加载根节点
const res = await api.getRootNodes({
page: this.currentPage,
size: this.pageSize
})
return resolve(res.data)
}
if (node.level >= 1) {
// 加载子节点
const res = await api.getChildrenNodes({
parentId: node.data.id,
page: 1,
size: 10
})
return resolve(res.data)
}
}
}
}
以上方法可以根据具体需求选择或组合使用,实现Vue中的树形分页功能。







