Skip to content

useExtraMenu 双列子菜单状态机

@fx/layouts 双列布局(two-column / mixed-two-column)第二列的状态机,移植自上游 useExtraMenu:hover / 点击第一列图标 → extraMenus 跟随该一级 children;鼠标移出侧区 → 回落到当前路由对应的根子树;路由变化重算。

签名

ts
function useExtraMenu(
  menusSource: () => LayoutMenuNode[],
  options?: {
    navigation?: (path: string) => Promise<unknown>
    route?: Ref<RouteLocationNormalizedLoaded>
  },
): {
  extraMenus: Ref<LayoutMenuNode[]>           // 第二列渲染的子树
  extraActiveMenu: Ref<string | null>         // 激活一级 path
  sidebarExtraVisible: Ref<boolean>           // extra 列是否可见(有子树时)
  defaultSubMap: Map<string, string>          // 一级 → 最后激活子路径
  handleMixedMenuSelect: (menu: LayoutMenuNode) => Promise<void>  // 第一列点击
  handleMenuMouseEnter: (menu: LayoutMenuNode) => void            // 第一列 hover
  handleSideMouseLeave: () => void                                 // 侧区 mouseleave 回落
  calcExtraMenus: (path: string) => void
}

用法

ts
const extra = useExtraMenu(() => business.menus, {
  navigation: (p) => router.push(p),
  route: router.currentRoute,
})
vue
<FxIconColumn
  :items="menus"
  :active-id="extra.extraActiveMenu.value"
  @select="extra.handleMixedMenuSelect"
  @hover="extra.handleMenuMouseEnter"
/>
<FxLayoutExtraMenu :menus="extra.extraMenus.value" :title="title" />

<!-- FxLayout 侧区容器 mouseleave 事件接 handleSideMouseLeave -->
<FxLayout @sidebar-mouse-leave="extra.handleSideMouseLeave" />

语义

  • 点击第一列:有子级 → extra 切换 + 导航到 defaultSubMap 记忆路径;无子级 → sidebarExtraVisible=false(FxLayout extra 列收起)直接导航
  • 路由变化:反查重算 extra 子树与激活态
  • handleMenuMouseEnter / handleSideMouseLeave(hover 跟随 / 移出回落)为可选 API——BasicLayout 默认不接(产品决策:extra 列只随点击与路由变化,无 hover 跟随),需要 hover 行为的消费方可自行接线