Skip to content

[Feature] 支持将同一动态路由(不同 params)合并为单个标签页,且该配置需能在 dynamic(后端下发)路由模式下生效 #943

Description

@guo0588

描述

中后台大量详情类页面使用动态参数路由,例如 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 只有类型声明与读取两处,模板内置路由里没有任何一个实际配置过它。)

建议的解决方案

  1. 提供一种方式,让"同一路由 + 不同 params/query"只保留一个标签页;
  2. 该配置在 dynamic(后端下发)路由模式下同样生效;
  3. 切换参数时,已有标签页内容需要刷新(不能停留在上一个 id 的数据)。

替代方案

No response

额外的上下文

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions