vue如何实现menu
Vue 实现 Menu 的方法
使用 Vue Router 实现导航菜单
在 Vue 项目中,可以利用 Vue Router 配合 <router-link> 组件实现导航菜单。通过动态渲染路由列表生成菜单项,并利用 v-for 指令简化代码。
<template>
<div class="menu">
<router-link
v-for="item in menuItems"
:key="item.path"
:to="item.path"
active-class="active"
>
{{ item.title }}
</router-link>
</div>
</template>
<script>
export default {
data() {
return {
menuItems: [
{ path: '/home', title: '首页' },
{ path: '/about', title: '关于' },
{ path: '/contact', title: '联系' }
]
}
}
}
</script>
<style>
.menu a {
margin-right: 15px;
text-decoration: none;
}
.menu a.active {
font-weight: bold;
color: #42b983;
}
</style>
使用第三方 UI 库快速实现
Element UI、Ant Design Vue 等流行库提供现成的 Menu 组件。以 Element UI 为例:

<template>
<el-menu
mode="horizontal"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b"
>
<el-menu-item index="1">首页</el-menu-item>
<el-submenu index="2">
<template #title>产品</template>
<el-menu-item index="2-1">选项1</el-menu-item>
<el-menu-item index="2-2">选项2</el-menu-item>
</el-submenu>
<el-menu-item index="3">联系我们</el-menu-item>
</el-menu>
</template>
<script>
import { ElMenu, ElMenuItem, ElSubmenu } from 'element-plus'
export default {
components: { ElMenu, ElMenuItem, ElSubmenu }
}
</script>
自定义递归菜单组件
对于多级嵌套菜单结构,可创建递归组件处理无限层级:

<!-- MenuItem.vue -->
<template>
<li>
<div @click="toggle">
{{ item.name }}
<span v-if="hasChildren">[{{ isOpen ? '-' : '+' }}]</span>
</div>
<ul v-show="isOpen && hasChildren">
<MenuItem
v-for="child in item.children"
:key="child.id"
:item="child"
/>
</ul>
</li>
</template>
<script>
export default {
name: 'MenuItem',
props: ['item'],
data() {
return { isOpen: false }
},
computed: {
hasChildren() {
return this.item.children && this.item.children.length
}
},
methods: {
toggle() {
if (this.hasChildren) this.isOpen = !this.isOpen
}
}
}
</script>
响应式侧边栏菜单
结合 Vuex 管理菜单状态,实现可折叠的侧边栏:
<template>
<div :class="['sidebar', { 'collapsed': isCollapsed }]">
<div class="toggle-btn" @click="toggleCollapse">☰</div>
<nav>
<ul>
<li v-for="item in menu" :key="item.id">
<router-link :to="item.path">
<i :class="item.icon"></i>
<span class="menu-text">{{ item.text }}</span>
</router-link>
</li>
</ul>
</nav>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
export default {
computed: {
...mapState(['isCollapsed', 'menu'])
},
methods: {
...mapMutations(['toggleCollapse'])
}
}
</script>
<style>
.sidebar {
width: 250px;
transition: width 0.3s;
}
.sidebar.collapsed {
width: 60px;
}
.menu-text {
transition: opacity 0.3s;
}
.collapsed .menu-text {
opacity: 0;
}
</style>
动态权限菜单实现
根据用户权限动态生成菜单,结合后端接口数据:
// 在导航守卫中处理
router.beforeEach(async (to, from, next) => {
if (!store.state.menuLoaded) {
const { data } = await axios.get('/api/user/menus')
const formattedMenu = formatRoutes(data)
formattedMenu.forEach(route => {
router.addRoute(route)
})
store.commit('SET_MENU', data)
store.commit('SET_MENU_LOADED', true)
return next(to.path)
}
next()
})
// 前端菜单过滤方法
function filterMenu(menu, permissions) {
return menu.filter(item => {
if (item.children) {
item.children = filterMenu(item.children, permissions)
}
return !item.meta?.permission || permissions.includes(item.meta.permission)
})
}






