vue实现菜单调用
Vue 实现动态菜单调用的方法
使用路由配置生成菜单
在 Vue 项目中,可以通过路由配置自动生成菜单结构。路由配置通常包含 path、name、meta 等信息,这些信息可用于构建菜单项。
// router/index.js
const routes = [
{
path: '/dashboard',
name: 'Dashboard',
meta: { title: '控制台', icon: 'el-icon-s-home' }
},
{
path: '/user',
name: 'User',
meta: { title: '用户管理', icon: 'el-icon-user' },
children: [
{
path: 'list',
name: 'UserList',
meta: { title: '用户列表' }
}
]
}
]
在组件中遍历路由配置生成菜单:
<template>
<el-menu :router="true">
<template v-for="route in $router.options.routes">
<el-submenu
v-if="route.children"
:index="route.path"
:key="route.path"
>
<template #title>
<i :class="route.meta.icon"></i>
<span>{{ route.meta.title }}</span>
</template>
<el-menu-item
v-for="child in route.children"
:key="child.path"
:index="child.path"
>
{{ child.meta.title }}
</el-menu-item>
</el-submenu>
<el-menu-item
v-else
:index="route.path"
:key="route.path"
>
<i :class="route.meta.icon"></i>
<span>{{ route.meta.title }}</span>
</el-menu-item>
</template>
</el-menu>
</template>
从后端API获取菜单数据
实际项目中,菜单数据通常由后端根据用户权限返回。可以创建 menuService 获取数据:
// services/menuService.js
export const getMenus = () => {
return axios.get('/api/menus')
}
在组件中调用并渲染:

<script>
import { getMenus } from '@/services/menuService'
export default {
data() {
return {
menus: []
}
},
async created() {
this.menus = await getMenus()
}
}
</script>
<template>
<el-menu>
<template v-for="menu in menus">
<el-submenu
v-if="menu.children"
:index="menu.id"
:key="menu.id"
>
<template #title>{{ menu.title }}</template>
<el-menu-item
v-for="child in menu.children"
:key="child.id"
:index="child.path"
>
{{ child.title }}
</el-menu-item>
</el-submenu>
<el-menu-item
v-else
:index="menu.path"
:key="menu.id"
>
{{ menu.title }}
</el-menu-item>
</template>
</el-menu>
</template>
递归组件实现多级菜单
对于深层级菜单,可以使用递归组件:
<template>
<el-menu>
<menu-item
v-for="item in menus"
:key="item.id"
:item="item"
/>
</el-menu>
</template>
<script>
import MenuItem from './MenuItem.vue'
export default {
components: { MenuItem },
data() {
return {
menus: [
{
id: 1,
title: '系统管理',
children: [
{
id: 2,
title: '用户管理',
children: [
{ id: 3, title: '添加用户', path: '/user/add' }
]
}
]
}
]
}
}
}
</script>
MenuItem.vue 组件:

<template>
<el-submenu v-if="item.children" :index="item.id">
<template #title>{{ item.title }}</template>
<menu-item
v-for="child in item.children"
:key="child.id"
:item="child"
/>
</el-submenu>
<el-menu-item v-else :index="item.path">
{{ item.title }}
</el-menu-item>
</template>
<script>
export default {
name: 'MenuItem',
props: ['item']
}
</script>
权限控制实现
结合权限系统,可以过滤用户可见的菜单项:
// utils/auth.js
export const filterMenus = (menus, permissions) => {
return menus.filter(menu => {
if (menu.permission && !permissions.includes(menu.permission)) {
return false
}
if (menu.children) {
menu.children = filterMenus(menu.children, permissions)
}
return true
})
}
在组件中使用:
<script>
import { filterMenus } from '@/utils/auth'
import { getMenus } from '@/services/menuService'
export default {
computed: {
permissions() {
return this.$store.state.user.permissions
}
},
async created() {
const allMenus = await getMenus()
this.menus = filterMenus(allMenus, this.permissions)
}
}
</script>
动态路由与菜单结合
对于权限系统,可能需要动态添加路由:
// router/index.js
export function generateRoutes(menus) {
const routes = []
menus.forEach(menu => {
const route = {
path: menu.path,
name: menu.name,
component: () => import(`@/views/${menu.component}`)
}
if (menu.children) {
route.children = generateRoutes(menu.children)
}
routes.push(route)
})
return routes
}
// 在登录后调用
const newRoutes = generateRoutes(menusFromBackend)
router.addRoutes(newRoutes)






