实现树形菜单vue
使用递归组件实现树形菜单
在Vue中实现树形菜单最常用的方法是使用递归组件。递归组件是指组件在其模板中调用自身,这种模式非常适合展示嵌套的树形数据结构。
创建树形菜单组件TreeMenu.vue:
<template>
<ul>
<li v-for="item in treeData" :key="item.id">
{{ item.name }}
<TreeMenu v-if="item.children" :treeData="item.children"/>
</li>
</ul>
</template>
<script>
export default {
name: 'TreeMenu',
props: {
treeData: {
type: Array,
required: true
}
}
}
</script>
准备树形数据结构
树形菜单需要特定的数据结构支持,通常是一个包含嵌套children的数组对象。示例数据结构如下:

const treeData = [
{
id: 1,
name: '节点1',
children: [
{
id: 2,
name: '子节点1',
children: [
{ id: 3, name: '孙节点1' }
]
}
]
},
{
id: 4,
name: '节点2'
}
]
添加展开/折叠功能
为树形菜单添加交互功能,可以控制子节点的显示与隐藏:
<template>
<ul>
<li v-for="item in treeData" :key="item.id">
<div @click="toggle(item)">
{{ item.name }}
<span v-if="hasChildren(item)">{{ item.expanded ? '-' : '+' }}</span>
</div>
<TreeMenu
v-if="item.children && item.expanded"
:treeData="item.children"
/>
</li>
</ul>
</template>
<script>
export default {
methods: {
toggle(item) {
if(this.hasChildren(item)) {
this.$set(item, 'expanded', !item.expanded)
}
},
hasChildren(item) {
return item.children && item.children.length
}
}
}
</script>
使用插槽自定义节点内容
通过插槽机制可以灵活自定义每个节点的显示内容:

<template>
<ul>
<li v-for="item in treeData" :key="item.id">
<slot :item="item">
<div @click="toggle(item)">
{{ item.name }}
</div>
</slot>
<TreeMenu
v-if="item.children && item.expanded"
:treeData="item.children"
>
<template v-slot="{ item }">
<slot :item="item"/>
</template>
</TreeMenu>
</li>
</ul>
</template>
添加选中状态功能
实现节点选中功能需要管理当前选中的节点:
<script>
export default {
props: {
value: {
type: [String, Number],
default: null
}
},
methods: {
selectNode(id) {
this.$emit('input', id)
}
}
}
</script>
在父组件中使用:
<TreeMenu
v-model="selectedNode"
:treeData="treeData"
/>
使用第三方库
如果需要更复杂的功能,可以考虑使用专门处理树形结构的Vue组件库:
- Vue Tree Component
- Element UI Tree
- Vuetify Treeview
- Vue Draggable Tree
这些库通常提供拖拽排序、复选框选择、异步加载等高级功能,适合复杂场景使用。






