vue 实现菜单栏
Vue 实现菜单栏的方法
使用 Vue Router 实现动态菜单
通过 Vue Router 可以方便地实现动态菜单栏,结合路由配置生成菜单项。
// router/index.js
const routes = [
{
path: '/home',
name: 'Home',
component: Home,
meta: { title: '首页', icon: 'el-icon-house' }
},
{
path: '/about',
name: 'About',
component: About,
meta: { title: '关于', icon: 'el-icon-info' }
}
]
<!-- Menu.vue -->
<template>
<div class="menu">
<router-link
v-for="route in routes"
:key="route.name"
:to="route.path"
class="menu-item"
>
<i :class="route.meta.icon"></i>
<span>{{ route.meta.title }}</span>
</router-link>
</div>
</template>
<script>
export default {
computed: {
routes() {
return this.$router.options.routes.filter(r => r.meta)
}
}
}
</script>
使用 Element UI 的菜单组件
如果项目使用 Element UI,可以直接使用其提供的菜单组件。

<template>
<el-menu
:default-active="activeIndex"
mode="horizontal"
@select="handleSelect"
>
<el-menu-item index="1">首页</el-menu-item>
<el-submenu index="2">
<template #title>产品</template>
<el-menu-item index="2-1">产品列表</el-menu-item>
<el-menu-item index="2-2">产品详情</el-menu-item>
</el-submenu>
<el-menu-item index="3">关于我们</el-menu-item>
</el-menu>
</template>
<script>
export default {
data() {
return {
activeIndex: '1'
}
},
methods: {
handleSelect(key) {
console.log(key)
}
}
}
</script>
实现递归菜单组件
对于多层嵌套的菜单结构,可以使用递归组件实现。

<!-- RecursiveMenu.vue -->
<template>
<ul class="menu">
<li v-for="item in menuData" :key="item.id">
<a :href="item.path">{{ item.title }}</a>
<recursive-menu
v-if="item.children && item.children.length"
:menu-data="item.children"
/>
</li>
</ul>
</template>
<script>
export default {
name: 'RecursiveMenu',
props: {
menuData: {
type: Array,
required: true
}
}
}
</script>
响应式菜单实现
使用 Vue 的响应式特性,可以根据屏幕尺寸切换菜单显示方式。
<template>
<div class="menu-container">
<button @click="toggleMenu">☰</button>
<nav :class="{ 'show': isMenuOpen }">
<ul>
<li v-for="item in menuItems" :key="item.id">
<a :href="item.link">{{ item.text }}</a>
</li>
</ul>
</nav>
</div>
</template>
<script>
export default {
data() {
return {
isMenuOpen: false,
menuItems: [
{ id: 1, text: '首页', link: '/' },
{ id: 2, text: '产品', link: '/products' }
]
}
},
methods: {
toggleMenu() {
this.isMenuOpen = !this.isMenuOpen
}
}
}
</script>
<style>
@media (max-width: 768px) {
nav {
display: none;
}
nav.show {
display: block;
}
}
</style>
使用 Vuex 管理菜单状态
对于复杂的应用,可以使用 Vuex 集中管理菜单状态。
// store/modules/menu.js
export default {
state: {
collapsed: false,
activeMenu: 'home'
},
mutations: {
toggleCollapse(state) {
state.collapsed = !state.collapsed
},
setActiveMenu(state, menu) {
state.activeMenu = menu
}
}
}
<template>
<div :class="{ 'collapsed': isCollapsed }">
<menu-item
v-for="item in menuItems"
:key="item.id"
:item="item"
:is-active="activeMenu === item.id"
@click="selectMenu(item.id)"
/>
<button @click="toggleCollapse">折叠/展开</button>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
export default {
computed: {
...mapState('menu', ['isCollapsed', 'activeMenu'])
},
methods: {
...mapMutations('menu', ['toggleCollapse', 'setActiveMenu']),
selectMenu(menuId) {
this.setActiveMenu(menuId)
}
}
}
</script>






