vue实现菜单效果
Vue 实现菜单效果的方法
基础菜单结构
使用 Vue 的 v-for 指令动态渲染菜单项,结合 v-if 或 v-show 控制子菜单的显示隐藏。
<template>
<div class="menu">
<div
v-for="item in menuItems"
:key="item.id"
@click="toggleSubMenu(item)"
>
{{ item.title }}
<div v-show="item.isOpen" class="submenu">
<div v-for="subItem in item.children" :key="subItem.id">
{{ subItem.title }}
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
menuItems: [
{
id: 1,
title: '菜单1',
isOpen: false,
children: [
{ id: 11, title: '子菜单1' },
{ id: 12, title: '子菜单2' }
]
},
{
id: 2,
title: '菜单2',
isOpen: false,
children: [
{ id: 21, title: '子菜单1' }
]
}
]
}
},
methods: {
toggleSubMenu(item) {
item.isOpen = !item.isOpen
}
}
}
</script>
<style>
.menu {
width: 200px;
}
.submenu {
padding-left: 20px;
}
</style>
递归组件实现多级菜单
对于复杂的多级菜单,可以使用递归组件实现。

<template>
<div class="menu-container">
<menu-item
v-for="item in menuData"
:key="item.id"
:item="item"
/>
</div>
</template>
<script>
import MenuItem from './MenuItem.vue'
export default {
components: {
MenuItem
},
data() {
return {
menuData: [
{
id: 1,
title: '一级菜单',
children: [
{
id: 11,
title: '二级菜单',
children: [
{ id: 111, title: '三级菜单' }
]
}
]
}
]
}
}
}
</script>
MenuItem.vue 组件:
<template>
<div>
<div @click="toggle">
{{ item.title }}
</div>
<div v-show="isOpen" v-if="item.children">
<menu-item
v-for="child in item.children"
:key="child.id"
:item="child"
/>
</div>
</div>
</template>
<script>
export default {
name: 'MenuItem',
props: {
item: Object
},
data() {
return {
isOpen: false
}
},
methods: {
toggle() {
this.isOpen = !this.isOpen
}
}
}
</script>
使用 Vue Router 实现路由菜单
结合 Vue Router 可以创建导航菜单。

<template>
<nav>
<router-link
v-for="route in routes"
:key="route.path"
:to="route.path"
>
{{ route.meta.title }}
</router-link>
</nav>
</template>
<script>
export default {
computed: {
routes() {
return this.$router.options.routes.filter(
route => route.meta && route.meta.showInMenu
)
}
}
}
</script>
使用第三方库
对于更复杂的需求,可以考虑使用以下 Vue 菜单组件库:
- Element UI 的
el-menu - Ant Design Vue 的
a-menu - Vue Context Menu 实现右键菜单
动画效果
为菜单添加过渡动画增强用户体验。
<template>
<transition name="slide">
<div class="menu" v-show="isVisible">
<!-- 菜单内容 -->
</div>
</transition>
</template>
<style>
.slide-enter-active, .slide-leave-active {
transition: all 0.3s ease;
}
.slide-enter, .slide-leave-to {
transform: translateX(-100%);
}
</style>






