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
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
用法
ts
const extra = useExtraMenu(() => business.menus, {
navigation: (p) => router.push(p),
route: router.currentRoute,
})1
2
3
4
2
3
4
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" />1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
语义
- 点击第一列:有子级 → extra 切换 + 导航到
defaultSubMap记忆路径;无子级 →sidebarExtraVisible=false(FxLayout extra 列收起)直接导航 - 路由变化:反查重算 extra 子树与激活态
handleMenuMouseEnter/handleSideMouseLeave(hover 跟随 / 移出回落)为可选 API——BasicLayout 默认不接(产品决策:extra 列只随点击与路由变化,无 hover 跟随),需要 hover 行为的消费方可自行接线
