一文教你实现vue-router动态路由菜单
一文教你实现vue-router动态路由菜单
😀大家好!我是向阳🌞,一个想成为优秀全栈开发工程师的有志青年!
📔今天来说一说如何实现vue-router动态路由菜单。
1.前言
在后台管理系统或复杂前端应用中,动态路由菜单是不可缺少的。它需要根据用户权限、业务场景动态展示不同的导航结构。本文将手把手教你如何利用Vue Router的meta字段和Ant Design Vue的菜单组件,实现灵活的动态路由菜单。
在没有实现动态路由的时候,你只能重新在头部菜单栏一个一个再添加上你需要展示的菜单项,但使用动态路由后,你不再需要在routes.ts中写一遍,再到头部菜单栏写一遍。’
本篇文章代码是使用ant-design-vue组件和vue-router完成的。
2.实现步骤
2.1.路由初始化
我们这里把要使用的路由和配置分离开来,不直接写在createRouter中,因为我们后面要对routes进行过滤。

index.ts代码演示:
const router = createRouter({
history: createWebHistory(),
routes,
})
2.2.路由配置与meta字段设计
过滤的核心就是使用vue-router提供的属性meta来进行过滤,看下面的代码中,我们的登录页面和注册页面是不需要展示在头部导航栏上的,所以我们来给他们指定一个hideInMenu属性,当设置为true时,则进行隐藏不展示。
routes.ts代码演示:
export const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: '主页',
component: HomePage,
meta: {
icon: () => h(HomeOutlined),
},
},
{
path: '/user/login',
name: '用户登录',
component: UserLoginPage,
meta: {
hideInMenu: true,
access: ACCESS_ENUM.NOT_LOGIN,
},
},
{
path: '/user/register',
name: '用户注册',
component: UserRegisterPage,
meta: {
hideInMenu: true,
access: ACCESS_ENUM.NOT_LOGIN,
},
},
]
2.3. 菜单过滤
接下来,我们在头部导航栏组件中获取routes,使用计算属性computed进行动态计算过滤,如果路由中meta中的hideInMenu属性为true,则返回false,因为filter过滤是将返回true的元素保留下来,最后我们将获取到的元素进行转换,转换为菜单组件展示需要的元素属性。
其中有一行代码是进行权限校验,如果我们这里不做介绍,直接忽略掉即可。
// 过滤菜单项
import { routes } from '@/router/routes.ts'
const items = computed(() => {
return routes
.filter((item) => {
if (item?.meta?.hideInMenu) {
return false
}
// 根据权限过滤菜单,有权限则返回 true,则保留该菜单
// return checkAccess(loginUserStore.loginUser, item?.meta?.access as string)
return true
})
.map(menuToRouteItem) // 转换为菜单项格式
})
转换代码中,如果有孩子节点则进行进一步的转换,这样就可以完成菜单过滤了。
// 把路由项转换为菜单项
const menuToRouteItem = (item: any) => {
const isHome = item.path === '/'
return {
key: item.path,
label: item.name,
title: item.name,
icon: h(item.meta?.icon) ?? undefined,
children: item.children?.map((child: any) => menuToRouteItem(child)),
}
}
const menus = ref<MenuProps['items']>(items)
2.4.在菜单组件中设置
<a-menu
v-model:selectedKeys="current"
@click="doMenuClick"
mode="horizontal"
:items="menus"
class="custom-menu"
/>
上面代码中的current是被选中的菜单,doMenuClick是点击菜单后触发的事件。
const current = ref<string[]>(['/'])
const doMenuClick = ({ key }: any) => {
console.log(key)
router.push({
path: key,
})
}
3.展示效果
刚刚我们展示的代码当中,是设置了hideInMenu属性为true的,所以头部菜单栏没有进行展示。

我们现在去掉hideInMenu属性,或者你也可以设置属性为false,后续可以更方便的进行修改需不需要展示,代码如下:
export const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: '主页',
component: HomePage,
meta: {
icon: () => h(HomeOutlined),
},
},
{
path: '/user/login',
name: '用户登录',
component: UserLoginPage,
},
{
path: '/user/register',
name: '用户注册',
component: UserRegisterPage,
},
]
可以看到,用户登录和用户注册就展示出来了。

4.常见问题解答
-
Q:页面刷新后菜单选中状态丢失怎么办?
A:通过useRoute()获取当前路由路径,初始化时设置selectedKeys的值。 -
Q:如何实现菜单项的权限颗粒化控制?
A:在meta.access中定义权限标识,结合RBAC(基于角色的访问控制)或ABAC(基于属性的访问控制)方案。 -
Q:图标显示异常如何处理?
A:确保:- 图标组件已正确注册/导入
- 使用h()函数渲染Vue组件
- 第三方图标库已正确引入样式文件
结语
通过本文,你已经掌握了动态路由菜单的核心实现技巧。
本部分代码在我的一个项目中有完整使用,如有需要点击该链接:Github,欢迎Star⭐️学习!如有问题,欢迎在评论区留言讨论~
——👦[作者]:向阳256
——⏳[更新]:2025.4.15
——🥰本人技术有限,如果有不对指正需要更改或者有更好的方法,欢迎到评论区留言。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)