vue实现多级菜单
Vue 实现多级菜单的方法
递归组件实现
递归组件是处理多级菜单的常见方式,通过组件调用自身实现无限层级嵌套。
<template>
<ul>
<li v-for="item in menuData" :key="item.id">
{{ item.name }}
<menu-item v-if="item.children" :menuData="item.children"></menu-item>
</li>
</ul>
</template>
<script>
export default {
name: 'MenuItem',
props: {
menuData: {
type: Array,
required: true
}
}
}
</script>
动态组件实现
通过动态组件和v-for循环渲染多级菜单。
<template>
<div>
<div v-for="item in menuData" :key="item.id">
<div @click="toggle(item)">
{{ item.name }}
<span v-if="item.children">{{ item.expanded ? '-' : '+' }}</span>
</div>
<div v-if="item.expanded && item.children">
<menu :menuData="item.children"></menu>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Menu',
props: {
menuData: Array
},
methods: {
toggle(item) {
item.expanded = !item.expanded
}
}
}
</script>
使用Vue Router实现
结合Vue Router可以实现带路由功能的多级菜单。

<template>
<div>
<div v-for="route in routes" :key="route.path">
<router-link :to="route.path">{{ route.meta.title }}</router-link>
<div v-if="route.children">
<router-link
v-for="child in route.children"
:key="child.path"
:to="route.path + '/' + child.path"
>
{{ child.meta.title }}
</router-link>
</div>
</div>
</div>
</template>
使用第三方UI库
Element UI、Ant Design Vue等UI库提供了现成的多级菜单组件。
<template>
<el-menu :default-active="activeIndex">
<template v-for="item in menuData">
<el-submenu v-if="item.children" :index="item.id" :key="item.id">
<template slot="title">{{ item.name }}</template>
<el-menu-item
v-for="child in item.children"
:key="child.id"
:index="child.id"
>
{{ child.name }}
</el-menu-item>
</el-submenu>
<el-menu-item v-else :index="item.id" :key="item.id">
{{ item.name }}
</el-menu-item>
</template>
</el-menu>
</template>
数据格式示例
多级菜单通常需要特定的数据结构。

const menuData = [
{
id: 1,
name: '一级菜单',
children: [
{
id: 11,
name: '二级菜单',
children: [
{ id: 111, name: '三级菜单' }
]
}
]
}
]
样式处理技巧
多级菜单通常需要层级缩进样式。
.menu-item {
padding-left: 20px;
}
.submenu {
margin-left: 20px;
}
性能优化
对于大型菜单数据,可以考虑虚拟滚动优化。
<template>
<virtual-list :size="50" :remain="10">
<menu-item v-for="item in bigMenuData" :key="item.id" :item="item" />
</virtual-list>
</template>






