vue 实现多级菜单
实现多级菜单的基本思路
使用递归组件或动态路由结合嵌套数据结构(如树形结构)实现多级菜单渲染。核心是通过组件自身调用自身处理子菜单,并利用 v-for 和条件渲染控制层级展开。
数据结构示例
菜单数据通常为嵌套数组,每个菜单项包含 children 字段表示子菜单:

const menuData = [
{
title: "一级菜单1",
children: [
{ title: "二级菜单1-1", children: [] },
{ title: "二级菜单1-2", children: [
{ title: "三级菜单1-2-1", children: [] }
]}
]
},
{
title: "一级菜单2",
children: []
}
];
递归组件实现
创建 MenuComponent.vue,通过 name 属性实现递归调用:

<template>
<ul>
<li v-for="item in menuList" :key="item.title">
<span @click="toggleChildren(item)">{{ item.title }}</span>
<MenuComponent
v-if="item.showChildren && item.children.length"
:menuList="item.children"
/>
</li>
</ul>
</template>
<script>
export default {
name: "MenuComponent", // 关键:通过name实现递归
props: {
menuList: Array
},
methods: {
toggleChildren(item) {
item.showChildren = !item.showChildren;
}
}
};
</script>
动态路由集成
若需与路由结合,可在菜单数据中添加 path 字段,并通过 router-link 导航:
// 路由配置
const routes = [
{ path: '/menu1', component: Page1, children: [
{ path: 'submenu1', component: SubPage1 }
]}
];
<!-- 修改递归组件中的渲染部分 -->
<router-link v-if="item.path" :to="item.path">{{ item.title }}</router-link>
<span v-else @click="toggleChildren(item)">{{ item.title }}</span>
样式与交互优化
通过 CSS 控制缩进和动画增强用户体验:
ul {
list-style: none;
padding-left: 20px;
}
li {
margin: 5px 0;
transition: all 0.3s;
}
注意事项
- 性能:深层嵌套时需限制递归深度,避免大量渲染。
- 状态管理:若菜单状态需全局共享(如折叠状态),建议使用 Vuex 或 Pinia。
- 唯一键值:确保
key使用唯一标识(如id而非title)。






