vue 菜单实现
Vue 菜单实现方法
基于路由的动态菜单
在 Vue 项目中,可以利用 Vue Router 实现动态菜单。首先定义路由配置,包含菜单所需的元信息(如标题、图标等)。
const routes = [
{
path: '/dashboard',
name: 'Dashboard',
component: Dashboard,
meta: { title: '控制台', icon: 'el-icon-s-home' }
},
{
path: '/user',
name: 'User',
component: User,
meta: { title: '用户管理', icon: 'el-icon-user' }
}
]
通过 this.$router.options.routes 获取路由配置,渲染菜单组件:
<template>
<el-menu :default-active="$route.path" router>
<template v-for="route in $router.options.routes">
<el-menu-item
:index="route.path"
:key="route.path"
>
<i :class="route.meta.icon"></i>
<span>{{ route.meta.title }}</span>
</el-menu-item>
</template>
</el-menu>
</template>
递归实现多级菜单
对于嵌套菜单,需要使用递归组件处理多级路由:
<template>
<el-menu :default-active="$route.path" router>
<template v-for="item in menuData">
<sub-menu
v-if="item.children"
:key="item.path"
:item="item"
/>
<el-menu-item
v-else
:key="item.path"
:index="item.path"
>
<i :class="item.meta.icon"></i>
<span>{{ item.meta.title }}</span>
</el-menu-item>
</template>
</el-menu>
</template>
<script>
import SubMenu from './SubMenu.vue'
export default {
components: { SubMenu },
computed: {
menuData() {
return this.$router.options.routes
}
}
}
</script>
子菜单组件 SubMenu.vue:
<template>
<el-submenu :index="item.path">
<template #title>
<i :class="item.meta.icon"></i>
<span>{{ item.meta.title }}</span>
</template>
<template v-for="child in item.children">
<sub-menu
v-if="child.children"
:key="child.path"
:item="child"
/>
<el-menu-item
v-else
:key="child.path"
:index="child.path"
>
{{ child.meta.title }}
</el-menu-item>
</template>
</el-submenu>
</template>
权限控制菜单
结合权限系统过滤可见菜单项:
computed: {
filteredMenu() {
return this.$router.options.routes.filter(route => {
const requiredRole = route.meta.role
return !requiredRole || this.userRoles.includes(requiredRole)
})
}
}
使用 UI 组件库
Element UI 的菜单组件示例:
<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">选项1</el-menu-item>
<el-menu-item index="2-2">选项2</el-menu-item>
</el-submenu>
</el-menu>
Ant Design Vue 的菜单组件:
<a-menu v-model:selectedKeys="current" mode="horizontal">
<a-menu-item key="mail">
<template #icon>
<mail-outlined />
</template>
Navigation One
</a-menu-item>
<a-sub-menu key="sub">
<template #icon>
<setting-outlined />
</template>
<template #title>Navigation Three - Submenu</template>
<a-menu-item key="setting:1">Option 1</a-menu-item>
<a-menu-item key="setting:2">Option 2</a-menu-item>
</a-sub-menu>
</a-menu>
响应式菜单
通过 CSS 媒体查询实现响应式布局:
@media (max-width: 768px) {
.el-menu--horizontal {
flex-direction: column;
}
}
结合 Vue 的响应式数据控制菜单折叠:
<el-menu
:collapse="isCollapse"
:collapse-transition="false"
>
<!-- 菜单项 -->
</el-menu>
<button @click="isCollapse = !isCollapse">
{{ isCollapse ? '展开' : '折叠' }}
</button>
面包屑导航实现
配合菜单实现面包屑导航:
computed: {
breadcrumbs() {
const matched = this.$route.matched.filter(
item => item.meta && item.meta.title
)
return matched.map(item => ({
path: item.path,
title: item.meta.title
}))
}
}
模板部分:
<el-breadcrumb separator="/">
<el-breadcrumb-item
v-for="item in breadcrumbs"
:key="item.path"
:to="item.path"
>
{{ item.title }}
</el-breadcrumb-item>
</el-breadcrumb>






