Skip to content

useMixedMenu 混合菜单状态机

@fx/layouts 的混合布局(mixed-vertical / mixed-two-column)状态机:点击 header 一级菜单 → 记录 rootMenuPath、侧栏切到该一级的 children;defaultSubMap 记住每个一级下最后激活的子路径,切回即恢复(autoActivateChild 行为写死默认开启)。

签名

ts
function useMixedMenu(
  menusSource: () => LayoutMenuNode[],
  options?: {
    /** 导航函数(组件内传 router.push;测试可注入 mock) */
    navigation?: (path: string) => Promise<unknown>
    /** 当前路由(组件内传 router.currentRoute) */
    route?: Ref<RouteLocationNormalizedLoaded>
  },
): {
  headerMenus: ComputedRef<LayoutMenuNode[]>    // 一级(children 清空)
  sidebarMenus: ComputedRef<LayoutMenuNode[]>   // 拆分激活时为子树,否则全量
  rootMenuPath: Ref<string | null>              // 激活一级 path
  splitSideMenus: Ref<LayoutMenuNode[]>         // 拆分子树
  defaultSubMap: Map<string, string>            // 一级 → 最后激活子路径
  handleMenuSelect: (menu: LayoutMenuNode) => Promise<void>
  calcSideMenus: (path: string) => void
}

用法

ts
const mixed = useMixedMenu(() => business.menus, {
  navigation: (p) => router.push(p),
  route: router.currentRoute,
})

// header TopMenu 点击一级
await mixed.handleMenuSelect(menu)

// 侧栏渲染子树
<FxLayoutSidebar :menus="mixed.sidebarMenus.value" />

语义

  • 路由反查route 传入时 watch(immediate)当前路径,同步 rootMenuPath / splitSideMenus,并记录 defaultSubMap
  • 无子级一级handleMenuSelect 直接导航
  • 有子级一级:切 splitSideMenus + 导航到 defaultSubMap 记忆路径(无记忆则一级自身 path)