Vue Router递归过滤含inMenu布尔字段的路由及子路由问题
我来帮你搞定这个路由过滤的需求!你需要的是递归过滤所有层级的路由,不管是父路由还是子路由,只要meta.inMenu为false就把它从菜单列表里去掉。之前的代码要么只处理了顶层路由,要么递归逻辑有问题,我给你整理一个清晰的解决方案:
核心思路
因为Vue Router的路由是树形结构,所以必须用递归函数遍历每一层路由:
- 先过滤当前层级的路由,只保留
meta.inMenu为true的条目; - 对每个保留的路由,如果有
children,就递归处理子路由列表,替换掉原有的children; - 确保整个路由树里所有不符合条件的节点(包括子节点)都被移除。
完整代码实现
// 定义递归过滤函数 const filterMenuRoutes = (routes) => { return routes.filter(route => { // 跳过inMenu为false或没有meta.inMenu的路由 if (route.meta?.inMenu !== true) { return false; } // 递归处理子路由(如果存在) if (route.children && route.children.length > 0) { route.children = filterMenuRoutes(route.children); // 可选:如果父路由需要在子路由全被过滤后也隐藏,可添加以下判断 // return route.children.length > 0; } return true; }); }; // 在Vue组件中使用 const filteredRoutes = filterMenuRoutes(this.$router.options.routes);
代码解释
- 可选链操作符
?.:避免因为某些路由没有meta字段而报错; - 递归处理children:确保每一层子路由都被过滤,比如你示例里的
orderDetails路由(inMenu: false)会被自动移除; - 灵活调整逻辑:如果需要父路由在子路由全被过滤后也隐藏,只需取消注释代码里的
return route.children.length > 0;即可,默认是保留inMenu: true的父路由,不管有没有子路由。
用你的示例路由测试
你的示例路由经过过滤后,最终会变成这样:
[ { "path": "/orders", "component": { "name": "Orders", "__file": "src/views/Orders.vue" }, "meta": { "icon": "fa-history", "title": "Abwicklungen", "inMenu": true }, "children": [ { "path": "list", "name": "orderList", "component": { "name": "OrderList", "__file": "src/views/orders/list.vue" }, "meta": { "title": "Bestellliste", "icon": "fa-circle-o", "inMenu": true } }, { "path": "dailyclosing", "component": { "name": "OrderList", "__file": "src/views/orders/list.vue" }, "meta": { "title": "Tagesabschluss", "icon": "fa-check", "inMenu": true } } ] } ]
可以看到orderDetails子路由已经被成功过滤掉了,完全符合你的需求。
对比你之前的代码问题
- 第一段代码里的
o.route.meta是错误的,应该是o.meta,而且递归返回children.length的逻辑不够直观,容易出问题; - 第二段代码只处理了顶层路由,完全没有递归处理子路由,所以子路由里的
inMenu: false条目会被保留。
内容的提问来源于stack exchange,提问作者Kazuto
相关产品推荐
相关产品推荐

