vue实现树图
Vue实现树形图的方法
使用递归组件实现树形结构
递归组件是Vue中实现树形结构的常见方式。通过组件调用自身来渲染嵌套的子节点。
<template>
<div class="tree-node">
<div @click="toggle">{{ node.name }}</div>
<div v-show="isOpen" v-if="node.children" class="children">
<tree-node
v-for="child in node.children"
:key="child.id"
:node="child"
/>
</div>
</div>
</template>
<script>
export default {
name: 'TreeNode',
props: {
node: Object
},
data() {
return {
isOpen: false
}
},
methods: {
toggle() {
this.isOpen = !this.isOpen
}
}
}
</script>
使用第三方库vue-orgchart
vue-orgchart是一个专门用于构建组织结构图的Vue组件库,适合展示树形关系。

安装:
npm install vue-orgchart
使用示例:

<template>
<orgchart :datasource="treeData"></orgchart>
</template>
<script>
import OrgChart from 'vue-orgchart'
import 'vue-orgchart/dist/style.min.css'
export default {
components: { OrgChart },
data() {
return {
treeData: {
name: 'Root',
children: [
{ name: 'Child 1' },
{ name: 'Child 2',
children: [
{ name: 'Grandchild 1' },
{ name: 'Grandchild 2' }
]
}
]
}
}
}
}
</script>
使用D3.js与Vue结合
对于更复杂的树形图可视化,可以结合D3.js的强大图形能力。
<template>
<div ref="treeContainer"></div>
</template>
<script>
import * as d3 from 'd3'
export default {
props: ['treeData'],
mounted() {
this.renderTree()
},
methods: {
renderTree() {
const margin = {top: 40, right: 90, bottom: 50, left: 90}
const width = 660 - margin.left - margin.right
const height = 500 - margin.top - margin.bottom
const treeLayout = d3.tree().size([width, height])
const root = d3.hierarchy(this.treeData)
treeLayout(root)
const svg = d3.select(this.$refs.treeContainer)
.append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`)
// 绘制连线
svg.selectAll('.link')
.data(root.links())
.enter()
.append('path')
.attr('class', 'link')
.attr('d', d3.linkVertical()
.x(d => d.x)
.y(d => d.y))
// 绘制节点
const node = svg.selectAll('.node')
.data(root.descendants())
.enter()
.append('g')
.attr('class', 'node')
.attr('transform', d => `translate(${d.x},${d.y})`)
node.append('circle').attr('r', 10)
node.append('text')
.attr('dy', '.31em')
.attr('y', d => d.children ? -20 : 20)
.text(d => d.data.name)
}
}
}
</script>
<style>
.link {
fill: none;
stroke: #ccc;
stroke-width: 2px;
}
.node circle {
fill: #fff;
stroke: steelblue;
stroke-width: 3px;
}
.node text {
font: 12px sans-serif;
}
</style>
使用Element UI的树形组件
如果项目中使用Element UI,可以直接使用其树形组件实现简单的树形展示。
<template>
<el-tree
:data="treeData"
:props="defaultProps"
@node-click="handleNodeClick"
></el-tree>
</template>
<script>
export default {
data() {
return {
treeData: [{
label: 'Level 1',
children: [{
label: 'Level 2',
children: [{
label: 'Level 3'
}]
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
}
},
methods: {
handleNodeClick(data) {
console.log(data)
}
}
}
</script>
每种方法适用于不同场景,递归组件适合简单自定义需求,vue-orgchart适合组织结构图,D3.js适合复杂可视化,Element UI适合快速集成到现有项目中。






