bricks/aidocs/menu.md
2025-10-05 06:39:58 +08:00

367 lines
8.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# `bricks.Menu` 技术文档
> 本文档为 `bricks.Menu` 类的详细说明,基于其继承自 `bricks.VBox` 的结构和功能设计。
---
## 概述
`bricks.Menu` 是一个用于构建可交互菜单界面组件的类,继承自 `bricks.VBox`。它支持嵌套子菜单、动态加载远程子菜单内容,并能响应菜单项点击事件以打开新窗口或更新目标组件内容。
该组件适用于构建侧边栏菜单、导航菜单或任何树形结构的交互式 UI。
---
## 继承关系
- **父类**: `bricks.VBox`
- **类型**: 自定义 UI 组件类Class-based
---
## 构造函数
```js
constructor(options)
```
### 参数
| 参数名 | 类型 | 说明 |
|-------|------|------|
| `options` | Object | 配置选项对象,继承自 `VBox` 并扩展以下属性 |
#### `options` 支持字段:
| 字段 | 类型 | 必需 | 默认值 | 说明 |
|------|------|------|--------|------|
| `items` | Array | ✅ | - | 菜单项数组,每个元素是一个菜单项配置对象(见下文) |
| `bgcolor` | String | ❌ | `"white"` | 背景颜色 |
| `target` | String | ❌ | - | 点击菜单项后内容加载的目标组件 ID 或特殊值 `'PopupWindow'` / `'Popup'` |
| `popup_options` | Object | ❌ | `{}` | 当目标为 PopupWindow 或 Popup 时使用的弹窗配置 |
> ⚠️ 注意:`target` 和 `popup_options` 可在单个菜单项中覆盖。
### 示例
```js
new bricks.Menu({
items: [
{ label: "首页", url: "/home" },
{ label: "用户管理", submenu: "/api/users" }
],
target: "main_content",
bgcolor: "#f5f5f5"
});
```
---
## 核心方法
### `create_submenu_container()`
创建一个用于容纳子菜单的容器(`VBox`),默认隐藏并带有缩进样式。
#### 返回值
- `{bricks.VBox}` —— 已配置好样式的子菜单容器
#### 样式设置
- `marginLeft: "15px"`
- `display: "none"`
---
### `async menu_clicked(event)`
处理菜单项被点击后的逻辑,根据配置打开页面、弹窗或注入到指定组件。
#### 参数
- `event`: DOM 事件对象,包含 `params` 字段,即菜单项数据。
#### 行为逻辑
1. 解析目标类型:
-`target === 'PopupWindow'`:创建 `PopupWindow` 实例
-`target === 'Popup'`:创建 `Popup` 实例
- 否则:查找对应 ID 的组件 (`bricks.getWidgetById`)
2. 使用 `widgetBuild` 动态生成 URL Widget 并插入目标组件
3. 触发全局 `command` 事件,携带原始菜单项参数
#### 触发事件
- `command`:携带菜单项信息,可用于外部监听执行命令
#### 日志输出
- 失败时打印错误日志:
- 目标组件未找到
- widget 构建失败
---
### `create_children(w, items)`
递归创建菜单项及其子菜单。
#### 参数
| 参数 | 类型 | 说明 |
|------|------|------|
| `w` | `bricks.Container` | 容器组件,用于添加生成的菜单项 |
| `items` | Array | 菜单项列表 |
#### 子菜单类型判断
| 条件 | 类型 | 说明 |
|------|------|------|
| `item.items` 存在 | 静态子菜单 | 直接递归创建 |
| `item.submenu` 存在 | 动态子菜单 | 点击时通过 URL 加载 |
| 其他 | 叶节点菜单项 | 绑定点击事件触发 `item_click` |
#### 内部行为
- 创建 `HBox` 表示菜单项
- 添加图标与文本
- 绑定点击/展开事件
- 支持国际化i18n、换行、左对齐等文本特性
---
### `async get_submenu_items(url)`
从远程 URL 获取子菜单数据JSON 格式)。
#### 参数
- `url` (String): 请求地址
#### 返回值
- `Promise<Array>`: 菜单项数组(`data.options.items`
#### 示例响应格式
```json
{
"options": {
"items": [
{ "label": "子项1", "url": "/sub1" },
{ "label": "子项2", "url": "/sub2" }
]
}
}
```
---
### `async load_submenu(container, event)`
懒加载动态子菜单内容。
#### 参数
- `container`: 子菜单容器(`VBox`
- `event`: 点击事件
#### 流程
1. 阻止事件冒泡
2. 若未加载过,则调用 `get_submenu_items()` 获取数据
3. 调用 `create_children()` 填充内容
4. 切换显示/隐藏状态
> ✅ 实现“点击展开 → 首次加载 → 缓存”机制
---
### `items_toggle_hide(w, event)`
切换静态子菜单的可见性。
#### 参数
- `w`: 子菜单容器
- `event`: 事件对象
#### 行为
- 执行 `toggle_hide()` 显示或隐藏
- 阻止事件冒泡
---
### `create_menuitem(item)`
创建单个菜单项 UI 组件(`HBox`)。
#### 参数
- `item`: 菜单项配置对象
| 属性 | 类型 | 说明 |
|------|------|------|
| `label` | String | 显示文本(支持 i18n |
| `icon` | String | 图标 URL |
| `url` | String | 导航链接 |
| `name` | String | 名称(备用标题) |
| 其他字段 | Any | 将直接挂载到返回的 widget 上 |
#### 返回值
- `{bricks.HBox}` 包含图标和文本的水平布局组件
#### 子组件
| 组件 | 类型 | 说明 |
|------|------|------|
| `iw` | `Icon``BlankIcon` | 图标区域,若无图标则占位 |
| `tw` | `Text` | 文本标签,启用自动换行、左对齐、填充样式 |
#### 样式类
- 应用 CSS 类名:`menuitem_css` 或默认 `'menuitem'`
---
### `regen_menuitem_event(item, event)`
菜单项点击事件处理器,用于非容器型菜单项。
#### 行为
- 记录日志
- 触发 `item_click` 事件并传递 `item`
- 阻止事件冒泡
---
## 事件系统
### 监听的事件
- `item_click`: 当菜单项被点击时触发,由 `regen_menuitem_event` 发出
### 分发的事件
| 事件名 | 数据 | 说明 |
|--------|------|------|
| `item_click` | `item` 对象 | 内部使用,通知上级处理点击 |
| `command` | `item` 对象 | 外部可监听,表示一个命令被执行 |
---
## 配置与扩展
### 默认弹窗选项获取
- `bricks.get_popupwindow_default_options()`
- `bricks.get_popup_default_options()`
可通过 `popup_options` 合并自定义配置(使用 `bricks.extend`
### 国际化支持
- `Text` 组件启用 `i18n: true`,支持多语言翻译
### 样式定制
- 可通过 `menuitem_css` 自定义菜单项样式类
- 使用 `set_css()``set_style()` 进行细粒度控制
---
## 注册与工厂模式
```js
bricks.Factory.register('Menu', bricks.Menu);
```
允许通过字符串标识符创建实例:
```js
bricks.createWidget("Menu", options);
```
---
## 使用场景示例
### 场景 1静态树形菜单
```js
const menu = new bricks.Menu({
items: [
{
label: "仪表盘",
icon: "/icons/dashboard.png",
url: "/dashboard"
},
{
label: "设置",
items: [
{ label: "账户", url: "/settings/account" },
{ label: "安全", url: "/settings/security" }
]
}
],
target: "main_panel"
});
```
### 场景 2动态加载子菜单
```js
const menu = new bricks.Menu({
items: [
{
label: "产品分类",
submenu: "/api/categories",
icon: "/icons/folder.png"
}
],
target: "PopupWindow",
popup_options: {
width: 800,
height: 600
}
});
```
---
## 注意事项
1. **性能优化**:动态子菜单仅在首次展开时请求数据,后续展开直接显示缓存内容。
2. **事件隔离**:所有点击事件均调用 `stopPropagation()` 防止意外冒泡。
3. **URL Widget 构建**:依赖 `bricks.widgetBuild()` 异步构建,需确保环境已初始化。
4. **目标组件存在性**:应确保 `target` 所指组件已注册且可用。
---
## 依赖模块
| 模块 | 用途 |
|------|------|
| `bricks.VBox`, `bricks.HBox` | 布局容器 |
| `bricks.Icon`, `bricks.BlankIcon` | 图标显示 |
| `bricks.Text` | 文本渲染与 i18n |
| `bricks.PopupWindow`, `bricks.Popup` | 弹窗组件 |
| `bricks.HttpJson` | JSON 数据请求 |
| `bricks.Factory`, `bricks.widgetBuild` | 组件工厂与异步构建 |
| `bricks.extend` | 对象合并工具函数 |
---
## 版本信息
- **作者**: Bricks Framework Team
- **版本**: v1.0(基础功能稳定)
- **最后更新**: 2025年4月5日
---
✅ *本组件适用于构建灵活、可扩展的菜单系统,推荐结合路由系统或 CMS 后台使用。*