vue elementui el-menu递归菜单
时间: 2025-05-13 16:40:10 浏览: 34
### Vue 中使用 Element Plus 的 `el-menu` 组件实现递归菜单
在 Vue 和 Element Plus 中,通过递归组件可以轻松实现动态加载的多级菜单结构。以下是详细的说明以及代码示例。
#### 动态菜单为何采用递归?
动态菜单通常具有不确定层数的特点,而递归是一种自然的方式来处理这种嵌套关系。通过递归调用自身组件,可以在每一层渲染对应的子菜单项,从而支持任意深度的菜单层次[^1]。
#### 如何实现递归菜单?
为了实现递归菜单,可以通过自定义一个递归组件来解析传入的数据列表,并逐层渲染出相应的菜单项和子菜单。具体步骤如下:
---
#### 1. 数据准备
假设我们有以下菜单数据结构作为输入:
```javascript
const menuList = [
{
name: '首页',
index: '1',
path: '/home'
},
{
name: '文档管理',
index: '2',
children: [
{ name: '新建文档', index: '2-1', path: '/docs/new' },
{ name: '编辑文档', index: '2-2', path: '/docs/edit' }
]
},
{
name: '设置',
index: '3',
children: [
{ name: '个人资料', index: '3-1', path: '/settings/profile' },
{
name: '安全中心',
index: '3-2',
children: [{ name: '修改密码', index: '3-2-1', path: '/settings/security/password' }]
}
]
}
];
```
上述数据是一个典型的树形结构,其中每个节点可能包含 `children` 属性表示其子菜单。
---
#### 2. 创建递归组件
创建一个名为 `<RecursiveMenu>` 的递归组件用于渲染菜单。
##### RecursiveMenu.vue 文件内容:
```vue
<template>
<div v-if="items && items.length">
<el-submenu :index="item.index" v-for="(item, idx) in items" :key="'submenu-' + idx" v-if="item.children">
<template #title>{{ item.name }}</template>
<recursive-menu :items="item.children"></recursive-menu> <!-- 自身递归 -->
</el-submenu>
<el-menu-item :index="item.index" v-for="(item, idx) in items" :key="'menuitem-' + idx" v-else>
{{ item.name }}
</el-menu-item>
</div>
</template>
<script>
export default {
name: "RecursiveMenu",
props: {
items: {
type: Array,
required: true
}
}
};
</script>
```
在这个模板中,当某个菜单项存在 `children` 属性时,会继续渲染自身的 `<RecursiveMenu>` 子组件;如果没有,则直接渲染为普通的 `<el-menu-item>`。
---
#### 3. 主页面集成
在主页面中引入并使用这个递归组件。
##### App.vue 或其他父组件文件:
```vue
<template>
<el-container style="height: 500px; border: 1px solid #eee;">
<el-aside width="200px">
<el-menu :default-active="activeIndex" @select="handleSelect">
<recursive-menu :items="menuList"></recursive-menu>
</el-menu>
</el-aside>
<el-main>Main Content Area</el-main>
</el-container>
</template>
<script>
import RecursiveMenu from './components/RecursiveMenu.vue';
export default {
components: {
RecursiveMenu
},
data() {
return {
activeIndex: '1',
menuList: [
{
name: '首页',
index: '1',
path: '/home'
},
{
name: '文档管理',
index: '2',
children: [
{ name: '新建文档', index: '2-1', path: '/docs/new' },
{ name: '编辑文档', index: '2-2', path: '/docs/edit' }
]
},
{
name: '设置',
index: '3',
children: [
{ name: '个人资料', index: '3-1', path: '/settings/profile' },
{
name: '安全中心',
index: '3-2',
children: [{ name: '修改密码', index: '3-2-1', path: '/settings/security/password' }]
}
]
}
]
};
},
methods: {
handleSelect(index) {
console.log('Selected:', index);
this.activeIndex = index;
}
}
};
</script>
```
在此部分中,我们将整个菜单数据传递给 `<RecursiveMenu>` 组件,并监听用户的点击事件以便更新激活状态。
---
#### 关键点解释
1. **递归逻辑**
在 `<RecursiveMenu>` 组件内部,如果检测到某一项含有 `children` 则再次调用自己,形成递归效果[^4]。
2. **默认选中项**
使用 `:default-active` 属性指定初始激活的菜单索引[^3]。
3. **事件绑定**
当用户点击某一菜单项时触发 `@select` 方法回调函数,可进一步扩展跳转功能或其他操作。
---
#### 进一步优化建议
- 可以加入路由链接支持,使每项菜单能够自动匹配当前路径。
- 添加权限控制机制,在实际应用中过滤掉无权访问的部分菜单项。
---
###
阅读全文
相关推荐




















