[Feature] 支持将同一动态路由(不同 params)合并为单个标签页,且该配置需能在 dynamic(后端下发)路由模式下生效
Author: guo0588Created Sep 17, 2026Updated Sep 17, 2026
描述
中后台大量详情类页面使用动态参数路由,例如 src/views/order/details/[id].vue。
用户在列表页依次点开不同记录时,每换一个 id 就会新增一个标签页(/details/5114、/details/5115、/details/5116 …),标签栏很快被同一页面的 N 个实例占满。
业务期望:这类路由只保留一个标签页,再次打开不同 id 时复用(并刷新)已有标签页,而不是继续新增。
现状与问题
1. meta.multiTab 只能区分 query,区分不了 params
// src/store/modules/tab/shared.ts
export function getTabIdByRoute(route: App.Global.TabRoute) {
const { path, query = {}, meta } = route;
let id = path;
if (meta.multiTab) {
const queryKeys = Object.keys(query).sort();
const qs = queryKeys.map(key => `${key}=${query[key]}`).join('&');
id = `${path}?${qs}`;
}
return id;
}这里的 path 是已解析的实际路径,/details/5114 与 /details/5115 天然就是两个不同 path,永远不会进入 multiTab 分支。multiTab 实际只对 /a?x=1 与 /a?x=2 这类"同 path 不同 query"有效。
2. 语义上只有"正向"开关,没有"反向"开关
multiTab = true 表示"允许多开"。但当同一路由默认就会被拆成多个标签页时(动态 params 场景),没有任何配置项能把它们合并为一个。
3. dynamic 模式下,meta.multiTab 根本传不进来(关键)
动态路由的 meta 是白名单映射,后端下发的字段只保留这 6 个:
// src/store/modules/route/index.ts
newRoute.meta = {
title: routeMeta?.title,
keepAlive: routeMeta.noCache,
localIcon: routeMeta.icon && routeMeta.icon !== '#' ? routeMeta.icon : defaultIcon,
href: routeMeta.href,
hideInMenu: routeMeta.hidden,
activeMenu: routeMeta.activeMenu
};multiTab 不在映射列表内 → 后端下发的 multiTab 被丢弃 → meta.multiTab 恒为 undefined。(另:全仓搜索 multiTab 只有类型声明与读取两处,模板内置路由里没有任何一个实际配置过它。)
建议的解决方案
- 提供一种方式,让"同一路由 + 不同 params/query"只保留一个标签页;
- 该配置在
dynamic(后端下发)路由模式下同样生效; - 切换参数时,已有标签页内容需要刷新(不能停留在上一个 id 的数据)。
替代方案
No response
额外的上下文
No response
Source: soybeanjs/soybean-admin