vue树形实现
Vue 树形组件实现方法
使用递归组件实现树形结构
递归组件是Vue中实现树形结构的常见方式。通过组件自身调用自身,可以动态渲染嵌套的树形数据。
<template>
<ul>
<li v-for="item in treeData" :key="item.id">
{{ item.label }}
<tree-node v-if="item.children" :treeData="item.children"></tree-node>
</li>
</ul>
</template>
<script>
export default {
name: 'TreeNode',
props: {
treeData: {
type: Array,
required: true
}
}
}
</script>
使用第三方UI库
Element UI、Ant Design Vue等流行UI库都提供了现成的树形组件,可以直接使用。
Element UI示例:

<el-tree
:data="treeData"
show-checkbox
node-key="id"
:props="defaultProps">
</el-tree>
<script>
export default {
data() {
return {
treeData: [{
label: '一级 1',
children: [{
label: '二级 1-1'
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
}
}
}
</script>
自定义可折叠树形组件
实现一个可展开/折叠的树形组件,需要管理每个节点的展开状态。
<template>
<div class="tree">
<div
v-for="node in data"
:key="node.id"
class="tree-node">
<div @click="toggleExpand(node)">
<span v-if="node.children">
{{ node.expanded ? '▼' : '▶' }}
</span>
{{ node.label }}
</div>
<div v-show="node.expanded && node.children" class="tree-children">
<tree :data="node.children"></tree>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Tree',
props: {
data: Array
},
methods: {
toggleExpand(node) {
this.$set(node, 'expanded', !node.expanded)
}
}
}
</script>
实现树形表格
结合表格实现树形数据展示,适用于需要同时展示多列数据的场景。

<template>
<table>
<tbody>
<tr v-for="item in flattenedData" :key="item.id">
<td :style="{ paddingLeft: (item.level * 20) + 'px' }">
<span @click="toggleExpand(item)" v-if="item.children">
{{ item.expanded ? '−' : '+' }}
</span>
{{ item.name }}
</td>
<td>{{ item.value }}</td>
</tr>
</tbody>
</table>
</template>
<script>
export default {
props: {
treeData: Array
},
computed: {
flattenedData() {
const flatten = (nodes, level = 0) => {
return nodes.reduce((acc, node) => {
acc.push({ ...node, level })
if (node.expanded && node.children) {
acc.push(...flatten(node.children, level + 1))
}
return acc
}, [])
}
return flatten(this.treeData)
}
},
methods: {
toggleExpand(item) {
this.$set(item, 'expanded', !item.expanded)
}
}
}
</script>
虚拟滚动优化大型树
对于大型树形数据,可以使用虚拟滚动技术优化性能。
<template>
<div class="virtual-tree" @scroll="handleScroll">
<div :style="{ height: totalHeight + 'px' }">
<div
v-for="item in visibleData"
:key="item.id"
:style="{
height: itemHeight + 'px',
paddingLeft: (item.level * 20) + 'px'
}">
{{ item.label }}
</div>
</div>
</div>
</template>
<script>
export default {
props: {
treeData: Array,
itemHeight: {
type: Number,
default: 30
},
visibleCount: {
type: Number,
default: 20
}
},
data() {
return {
startIndex: 0,
scrollTop: 0
}
},
computed: {
flattenedData() {
// 扁平化树形数据并计算level
},
totalHeight() {
return this.flattenedData.length * this.itemHeight
},
visibleData() {
return this.flattenedData.slice(
this.startIndex,
this.startIndex + this.visibleCount
)
}
},
methods: {
handleScroll(e) {
this.scrollTop = e.target.scrollTop
this.startIndex = Math.floor(this.scrollTop / this.itemHeight)
}
}
}
</script>
树形组件功能扩展
实际应用中可能需要添加以下功能:
- 节点选择/多选
- 拖拽排序
- 节点过滤搜索
- 懒加载
- 上下文菜单
- 节点编辑
根据具体需求选择合适的实现方式,对于复杂场景推荐使用成熟的UI库,简单场景可考虑自定义实现。性能优化方面需要注意大型数据集的渲染效率,必要时采用虚拟滚动技术。






