vue实现动态路由菜单
Vue 实现动态路由菜单的方法
路由配置与动态加载
动态路由的核心在于通过后端接口获取菜单数据,并映射为前端路由。通常需要在路由配置中使用 addRoute 方法动态添加路由。
// router/index.js
const router = createRouter({ /* 基础配置 */ });
// 假设从后端获取菜单数据
const fetchMenuData = async () => {
const response = await api.get('/menus');
return response.data;
};
// 动态添加路由
const setupDynamicRoutes = async () => {
const menus = await fetchMenuData();
menus.forEach(menu => {
router.addRoute({
path: menu.path,
component: () => import(`@/views/${menu.component}.vue`),
meta: { title: menu.title }
});
});
};
菜单组件渲染
动态菜单组件通常通过递归方式渲染多级菜单结构,结合 v-for 和条件判断实现层级嵌套。

<template>
<el-menu :router="true">
<template v-for="item in menuList" :key="item.path">
<el-submenu v-if="item.children" :index="item.path">
<template #title>{{ item.meta.title }}</template>
<menu-item :menuList="item.children" />
</el-submenu>
<el-menu-item v-else :index="item.path">
{{ item.meta.title }}
</el-menu-item>
</template>
</el-menu>
</template>
<script>
export default {
name: 'MenuItem',
props: {
menuList: { type: Array, required: true }
}
};
</script>
权限控制
动态路由常需结合权限验证,通过路由守卫检查用户是否有权访问目标路由。

router.beforeEach(async (to, from, next) => {
const hasToken = localStorage.getItem('token');
if (to.path === '/login') {
next();
} else if (!hasToken) {
next('/login');
} else if (!router.hasRoute(to.name)) {
await setupDynamicRoutes();
next(to.path); // 重定向到目标页
} else {
next();
}
});
数据格式示例
后端返回的菜单数据通常需要包含路由关键字段,建议格式如下:
[
{
"path": "/dashboard",
"component": "Dashboard",
"meta": { "title": "控制台" }
},
{
"path": "/user",
"component": "UserLayout",
"meta": { "title": "用户管理" },
"children": [
{
"path": "list",
"component": "UserList",
"meta": { "title": "用户列表" }
}
]
}
]
缓存处理
为避免重复加载路由,可在 Vuex 或 Pinia 中存储已加载的路由状态:
// store/modules/permission.js
state: {
loadedRoutes: []
},
mutations: {
SET_ROUTES(state, routes) {
state.loadedRoutes = routes;
}
}
注意事项
- 动态导入组件需确保 Webpack 能正确解析路径,建议使用明确的路径别名
- 404 页面应在静态路由中配置,动态路由添加后需手动重定向
- 菜单图标可通过
meta.icon字段扩展,结合第三方图标库使用






