vue中实现tree
Vue 中实现 Tree 组件
数据结构设计
Tree 组件通常需要一个嵌套的树形数据结构。每个节点包含 label、children 等属性。
const treeData = [
{
label: 'Node 1',
children: [
{
label: 'Node 1-1',
children: []
}
]
}
]
递归组件实现
使用 Vue 的递归组件特性实现 Tree。组件通过 name 属性调用自身。
<template>
<ul>
<li v-for="node in data" :key="node.label">
{{ node.label }}
<tree-node v-if="node.children && node.children.length" :data="node.children"/>
</li>
</ul>
</template>
<script>
export default {
name: 'TreeNode',
props: {
data: {
type: Array,
required: true
}
}
}
</script>
展开/折叠功能
通过 v-if 或 v-show 控制子节点的显示隐藏,添加点击事件切换状态。
<template>
<ul>
<li v-for="node in data" :key="node.label">
<span @click="toggle(node)">{{ node.expanded ? '-' : '+' }}</span>
{{ node.label }}
<tree-node v-if="node.expanded && node.children" :data="node.children"/>
</li>
</ul>
</template>
<script>
export default {
name: 'TreeNode',
props: {
data: {
type: Array,
required: true
}
},
methods: {
toggle(node) {
node.expanded = !node.expanded
}
}
}
</script>
选中状态管理
通过 v-model 或自定义事件实现节点选中功能。
<template>
<ul>
<li v-for="node in data" :key="node.label">
<input type="checkbox" v-model="node.checked" @change="handleCheck(node)">
{{ node.label }}
<tree-node v-if="node.expanded && node.children" :data="node.children"/>
</li>
</ul>
</template>
<script>
export default {
name: 'TreeNode',
props: {
data: {
type: Array,
required: true
}
},
methods: {
handleCheck(node) {
this.$emit('check-change', node)
}
}
}
</script>
动态加载节点
对于大数据量场景,实现按需加载子节点。
<template>
<ul>
<li v-for="node in data" :key="node.label">
<span @click="loadChildren(node)">{{ node.loading ? 'Loading...' : '+' }}</span>
{{ node.label }}
<tree-node v-if="node.children" :data="node.children"/>
</li>
</ul>
</template>
<script>
export default {
name: 'TreeNode',
props: {
data: {
type: Array,
required: true
}
},
methods: {
async loadChildren(node) {
if (!node.children) {
node.loading = true
node.children = await fetchChildren(node.id)
node.loading = false
}
}
}
}
</script>
样式优化
添加 CSS 样式提升 Tree 组件的视觉效果。
ul {
list-style-type: none;
padding-left: 20px;
}
li {
cursor: pointer;
margin: 5px 0;
}
span {
margin-right: 5px;
}
完整示例
整合上述功能实现完整的 Tree 组件。

<template>
<div class="tree">
<tree-node :data="treeData" @check-change="handleCheckChange"/>
</div>
</template>
<script>
import TreeNode from './TreeNode.vue'
export default {
components: {
TreeNode
},
data() {
return {
treeData: [
{
id: 1,
label: 'Root',
expanded: true,
children: [
{
id: 2,
label: 'Child 1',
children: []
}
]
}
]
}
},
methods: {
handleCheckChange(node) {
console.log('Node checked:', node)
}
}
}
</script>






