vue实现树形菜单
Vue 实现树形菜单的方法
递归组件实现
通过递归组件可以轻松实现树形结构。定义一个组件,该组件能够调用自身来渲染子节点。
<template>
<ul>
<li v-for="item in treeData" :key="item.id">
{{ item.name }}
<tree-menu v-if="item.children" :treeData="item.children" />
</li>
</ul>
</template>
<script>
export default {
name: 'TreeMenu',
props: {
treeData: {
type: Array,
required: true
}
}
}
</script>
使用第三方库
如果需要更复杂的功能,可以考虑使用第三方库如 vue-tree-list 或 vuejs-tree。
安装 vuejs-tree:
npm install vuejs-tree
使用示例:
<template>
<vuejs-tree :data="treeData" />
</template>
<script>
import VuejsTree from 'vuejs-tree'
export default {
components: {
VuejsTree
},
data() {
return {
treeData: [
{
text: 'Parent',
children: [
{ text: 'Child 1' },
{ text: 'Child 2' }
]
}
]
}
}
}
</script>
动态加载数据
对于大型树形结构,可以动态加载数据以提高性能。
<template>
<ul>
<li v-for="item in visibleData" :key="item.id" @click="toggleChildren(item)">
{{ item.name }}
<span v-if="item.children && !item.expanded">+</span>
<span v-if="item.children && item.expanded">-</span>
<tree-menu
v-if="item.expanded && item.children"
:treeData="item.children"
/>
</li>
</ul>
</template>
<script>
export default {
name: 'TreeMenu',
props: {
treeData: {
type: Array,
required: true
}
},
data() {
return {
visibleData: this.treeData.map(item => ({
...item,
expanded: false
}))
}
},
methods: {
toggleChildren(item) {
item.expanded = !item.expanded
}
}
}
</script>
添加样式和交互
为树形菜单添加样式和交互效果,提升用户体验。

<template>
<ul class="tree-menu">
<li
v-for="item in treeData"
:key="item.id"
:class="{ 'has-children': item.children }"
@click="toggleChildren(item)"
>
<span>{{ item.name }}</span>
<tree-menu
v-if="item.expanded && item.children"
:treeData="item.children"
/>
</li>
</ul>
</template>
<script>
export default {
name: 'TreeMenu',
props: {
treeData: {
type: Array,
required: true
}
},
methods: {
toggleChildren(item) {
if (item.children) {
item.expanded = !item.expanded
}
}
}
}
</script>
<style>
.tree-menu ul {
padding-left: 20px;
}
.tree-menu li {
list-style: none;
cursor: pointer;
}
.tree-menu li.has-children {
font-weight: bold;
}
</style>
以上方法可以根据实际需求选择或组合使用,以实现不同复杂度的树形菜单功能。






