FxTopMenu 水平菜单
@fx/layouts header 内的水平一级菜单,规格:一级项 40px 高 / radius 6 / 14px 字。有子级的项 hover 下拉级联子菜单(二级在下方弹出、三级及更深层在右侧逐级弹出,经典菜单栏形态)——级联面板由 FxCascadeMenu 组件驱动(与 FxMenu 折叠弹层同款规格:38px 项 / 14px 字 / 180px 等宽,侧栏折叠弹层已同步紧凑化);无子级项点击 emit select。容器宽度不足时,超出的一级项自动收进「⋯ 更多」按钮(hover 展开同款级联)。
基础用法
vue
<script setup lang="ts">
/**
* FxTopMenu 基础示例:水平菜单 + 级联子菜单 + 溢出收纳(⋯ 更多)
* hover 一级下拉二级、hover 二级右侧弹三级;叶子点击 emit select
*/
import { ref } from "vue"
import { FxTopMenu } from "@fx/layouts"
import type { LayoutMenuNode } from "@fx/layouts"
const items: LayoutMenuNode[] = [
{
id: 1,
name: "首页",
path: "/dashboard",
icon: "ep:home-filled",
menu_type: "menu",
children: [],
},
{
id: 2,
name: "系统管理",
path: "/system",
icon: "ep:setting",
menu_type: "directory",
children: [
{
id: 21,
name: "用户管理",
path: "/system/user",
icon: "ep:user",
menu_type: "menu",
children: [],
},
{
id: 22,
name: "权限配置",
path: null,
icon: "ep:key",
menu_type: "directory",
children: [
{
id: 221,
name: "角色管理",
path: "/system/role",
icon: null,
menu_type: "menu",
children: [],
},
{
id: 222,
name: "菜单管理",
path: "/system/menu",
icon: null,
menu_type: "menu",
children: [],
},
],
},
],
},
{
id: 3,
name: "监控",
path: "/monitor",
icon: "ep:monitor",
menu_type: "menu",
children: [],
},
]
const activeId = ref<string | null>("/dashboard")
const activePath = ref<string | null>("/dashboard")
const last = ref("(点击菜单项)")
function onSelect(menu: LayoutMenuNode) {
activeId.value = menu.path
last.value = `select: ${menu.name} → ${menu.path}`
}
</script>
<template>
<div class="demo-top-menu">
<div class="demo-header">
<FxTopMenu
:items="items"
:active-id="activeId"
:active-path="activePath"
@select="onSelect"
/>
</div>
<p class="demo-tip">{{ last }}</p>
</div>
</template>
<style scoped>
.demo-header {
height: 48px;
display: flex;
border-bottom: 1px solid var(--fx-border-color, #eee);
}
.demo-tip {
margin: 8px 0 0;
font-size: 12px;
color: #888;
}
</style>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
vue
<!-- horizontal 模式:完整树,叶子点击直接导航 -->
<FxTopMenu
:items="menus"
:active-id="findTopMenuContaining(menus, route.path)?.path ?? null"
:active-path="route.path"
@select="(menu) => menu.path && router.push(menu.path)"
/>
<!-- mixed 系模式:一级(去 children),点击切侧栏子树 -->
<FxTopMenu
:items="mixed.headerMenus.value"
:active-id="mixed.rootMenuPath.value"
:active-path="route.path"
@select="mixed.handleMenuSelect"
/>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Attributes
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| items | 菜单项(完整树或一级) | LayoutMenuNode[] | —(必填) |
| active-id | 激活一级 path(一级项高亮) | string | null | — |
| active-path | 当前路由 path(级联深层项按子树包含高亮) | string | null | null |
Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| select | 点击菜单项(叶子或无子级目录) | (menu: LayoutMenuNode) |
