利用vue实现树状图
Vue实现树状图的方法
使用递归组件实现树状结构
递归组件是Vue中实现树状结构的常见方式。通过组件调用自身,可以动态渲染任意层级的树形数据。
<template>
<div>
<tree-node :node="treeData"></tree-node>
</div>
</template>
<script>
export default {
components: {
TreeNode: {
name: 'TreeNode',
props: ['node'],
template: `
<div>
<div>{{ node.name }}</div>
<div v-if="node.children" style="margin-left: 20px">
<tree-node
v-for="child in node.children"
:key="child.id"
:node="child">
</tree-node>
</div>
</div>
`
}
},
data() {
return {
treeData: {
id: 1,
name: 'Root',
children: [
{
id: 2,
name: 'Child 1',
children: [
{ id: 4, name: 'Grandchild 1' },
{ id: 5, name: 'Grandchild 2' }
]
},
{
id: 3,
name: 'Child 2'
}
]
}
}
}
}
</script>
使用第三方库实现高级树状图
对于更复杂的需求,可以使用专门的树状图组件库如vue-tree-chart或vuejs-tree。
安装vue-tree-chart:

npm install vue-tree-chart
示例代码:
<template>
<div>
<tree-chart :data="treeData"></tree-chart>
</div>
</template>
<script>
import TreeChart from 'vue-tree-chart'
export default {
components: { TreeChart },
data() {
return {
treeData: {
name: 'Root',
children: [
{
name: 'Child 1',
children: [
{ name: 'Grandchild 1' },
{ name: 'Grandchild 2' }
]
},
{
name: 'Child 2'
}
]
}
}
}
}
</script>
实现可交互的树状图
添加展开/折叠功能:

<template>
<div>
<tree-node :node="treeData"></tree-node>
</div>
</template>
<script>
export default {
components: {
TreeNode: {
name: 'TreeNode',
props: ['node'],
data() {
return {
isExpanded: true
}
},
template: `
<div>
<div @click="isExpanded = !isExpanded">
{{ node.name }}
<span v-if="node.children">
{{ isExpanded ? '[-]' : '[+]' }}
</span>
</div>
<div
v-if="node.children && isExpanded"
style="margin-left: 20px">
<tree-node
v-for="child in node.children"
:key="child.id"
:node="child">
</tree-node>
</div>
</div>
`
}
},
data() {
return {
treeData: {
id: 1,
name: 'Root',
children: [
{
id: 2,
name: 'Child 1',
children: [
{ id: 4, name: 'Grandchild 1' },
{ id: 5, name: 'Grandchild 2' }
]
},
{
id: 3,
name: 'Child 2'
}
]
}
}
}
}
</script>
添加样式美化树状图
通过CSS增强视觉效果:
.tree-node {
margin: 5px 0;
cursor: pointer;
}
.tree-node-name {
padding: 5px;
background: #f5f5f5;
border-radius: 3px;
display: inline-block;
}
.tree-node-name:hover {
background: #e0e0e0;
}
.tree-children {
margin-left: 20px;
border-left: 1px dashed #ccc;
padding-left: 10px;
}
动态加载树状数据
实现异步加载子节点:
methods: {
async loadChildren(node) {
if (!node.childrenLoaded && node.hasChildren) {
const response = await fetch(`/api/nodes/${node.id}/children`)
node.children = await response.json()
node.childrenLoaded = true
}
}
}
在模板中添加加载方法:
<div @click="loadChildren(node); isExpanded = !isExpanded">
{{ node.name }}
</div>






