vue 实现多级菜单
实现多级菜单的核心思路
多级菜单通常通过递归组件或动态渲染实现,关键在于数据结构的设计和组件的嵌套逻辑。以下是一个基于Vue 3的完整实现方案。
数据结构设计
菜单数据建议使用嵌套结构,每个菜单项包含label、path和可选的children属性:
const menuData = [
{
label: "一级菜单",
path: "/level1",
children: [
{
label: "二级菜单",
path: "/level1/level2",
children: [...]
}
]
}
]
递归组件实现
创建MenuItem.vue作为递归组件:
<template>
<li>
<router-link v-if="!item.children" :to="item.path">
{{ item.label }}
</router-link>
<template v-else>
<a @click="toggle">{{ item.label }}</a>
<ul v-show="isOpen">
<menu-item
v-for="child in item.children"
:key="child.path"
:item="child"
/>
</ul>
</template>
</li>
</template>
<script setup>
import { ref } from 'vue';
const props = defineProps({
item: Object
});
const isOpen = ref(false);
const toggle = () => isOpen.value = !isOpen.value;
</script>
主组件集成
在父组件中引入并传递数据:
<template>
<ul class="menu">
<menu-item
v-for="item in menuData"
:key="item.path"
:item="item"
/>
</ul>
</template>
<script setup>
import MenuItem from './MenuItem.vue';
import menuData from './menuData.js';
</script>
样式优化
添加基础交互样式增强用户体验:
.menu ul {
padding-left: 1rem;
list-style: none;
}
.menu a {
display: block;
padding: 0.5rem;
cursor: pointer;
}
.menu a:hover {
background-color: #f0f0f0;
}
动态加载方案
如需异步加载菜单,可在组件中增加数据获取逻辑:
const fetchMenuData = async () => {
const res = await axios.get('/api/menu');
menuData.value = res.data;
};
权限控制集成
结合权限系统过滤菜单项:
const filteredMenu = computed(() => {
return menuData.value.filter(item =>
checkPermission(item.requiredRole)
);
});
注意事项
- 路由配置需与菜单路径匹配
- 深层嵌套时考虑添加展开/折叠动画
- 移动端需处理触摸事件
- 为无障碍访问添加ARIA属性
以上方案可根据实际需求调整,如改用el-menu等UI库组件可减少基础样式工作。关键点在于保持组件递归逻辑清晰和数据结构合理。







