vue实现菜单树
实现菜单树的基本思路
在Vue中实现菜单树通常需要递归组件来处理嵌套的树形结构数据。核心是通过组件自身调用自身的方式渲染子菜单,并利用CSS控制缩进和交互效果。
数据结构示例
菜单数据通常是一个嵌套结构的数组对象,每个节点包含标题、唯一标识、子节点等属性:
const menuData = [
{
id: 1,
title: '首页',
children: []
},
{
id: 2,
title: '产品管理',
children: [
{
id: 21,
title: '产品列表',
children: []
}
]
}
]
递归组件实现
创建名为TreeMenu.vue的组件:

<template>
<ul class="menu-tree">
<li v-for="item in treeData" :key="item.id">
<div @click="toggleChildren(item)">
{{ item.title }}
<span v-if="item.children?.length">[{{ item.isOpen ? '-' : '+' }}]</span>
</div>
<tree-menu
v-if="item.children && item.isOpen"
:tree-data="item.children"
class="sub-menu"
/>
</li>
</ul>
</template>
<script>
export default {
name: 'TreeMenu',
props: {
treeData: {
type: Array,
required: true
}
},
methods: {
toggleChildren(item) {
if (item.children?.length) {
this.$set(item, 'isOpen', !item.isOpen)
}
}
}
}
</script>
<style>
.menu-tree {
list-style: none;
padding-left: 20px;
}
.sub-menu {
margin-left: 15px;
}
</style>
使用组件
在父组件中引入并使用:
<template>
<div>
<tree-menu :tree-data="menuData" />
</div>
</template>
<script>
import TreeMenu from './TreeMenu.vue'
export default {
components: { TreeMenu },
data() {
return {
menuData: [...] // 你的菜单数据
}
}
}
</script>
进阶优化方向
添加默认展开/折叠控制

// 在数据初始化时添加状态
function initMenuData(data) {
return data.map(item => {
return {
...item,
isOpen: false,
children: item.children ? initMenuData(item.children) : []
}
})
}
添加路由跳转功能
<div @click="handleItemClick(item)">
{{ item.title }}
</div>
methods: {
handleItemClick(item) {
if (item.path) {
this.$router.push(item.path)
} else if (item.children?.length) {
this.toggleChildren(item)
}
}
}
使用第三方库
对于复杂需求可以考虑使用现成的树形组件库:
vue-tree-list:提供拖拽、复选框等功能element-ui的el-tree组件ant-design-vue的a-tree组件






