> For the complete documentation index, see [llms.txt](https://ak-scripts.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ak-scripts.gitbook.io/docs/yi-lai/markdown/ui-mo-kuai-dao-chu/cai-dan-menu.md).

# 菜单（Menu）

## 📋 Menu（菜单）模块导出文档

### 📋 概述

Menu 模块是 ak-lib 的菜单系统，支持鼠标/键盘操作、多层菜单、模块化结构、图标支持等功能。

### 🚀 导出方式

#### 客户端

```lua
exports['ak-lib']:Menu(data)
exports['ak-lib']:CloseMenu()
exports['ak-lib']:HideMenu()
exports['ak-lib']:UpdateMenu(data)
exports['ak-lib']:IsMenuOpen()
exports['ak-lib']:GetCurrentMenu()
```

#### 服务端

```lua
exports['ak-lib']:Menu(target, data)
exports['ak-lib']:CloseMenu(target)
exports['ak-lib']:HideMenu(target)
exports['ak-lib']:UpdateMenu(target, data)
```

### 📖 可用导出

#### 客户端

| 导出                 | 说明       | 参数             | 返回值                     |
| ------------------ | -------- | -------------- | ----------------------- |
| `Menu(data)`       | 打开菜单     | `data` (table) | boolean                 |
| `CloseMenu()`      | 关闭菜单     | -              | boolean                 |
| `HideMenu()`       | 隐藏菜单（别名） | -              | boolean                 |
| `UpdateMenu(data)` | 更新菜单     | `data` (table) | boolean                 |
| `IsMenuOpen()`     | 检查菜单是否打开 | -              | boolean, string (菜单 ID) |
| `GetCurrentMenu()` | 获取当前菜单数据 | -              | table / nil             |

#### 服务端

| 导出                         | 说明        | 参数                                | 返回值 |
| -------------------------- | --------- | --------------------------------- | --- |
| `Menu(target, data)`       | 向指定玩家打开菜单 | `target` (number), `data` (table) | nil |
| `CloseMenu(target)`        | 关闭指定玩家的菜单 | `target` (number)                 | nil |
| `HideMenu(target)`         | 隐藏指定玩家的菜单 | `target` (number)                 | nil |
| `UpdateMenu(target, data)` | 更新指定玩家的菜单 | `target` (number), `data` (table) | nil |

### 💡 使用示例

#### 客户端：基础使用

```lua
-- 基础菜单
exports['ak-lib']:Menu({
    id = 'main_menu',
    title = '主菜单',
    options = {
        {
            label = '选项 1',
            description = '这是选项 1 的描述',
            value = 'option1'
        },
        {
            label = '选项 2',
            description = '这是选项 2 的描述',
            value = 'option2'
        }
    },
    onSelect = function(option)
        print("选择了:", option.value)
    end
})

-- 带图标
exports['ak-lib']:Menu({
    id = 'vehicle_menu',
    title = '载具菜单',
    options = {
        {
            label = '锁定',
            icon = 'fa-solid fa-lock',
            value = 'lock'
        },
        {
            label = '解锁',
            icon = 'fa-solid fa-unlock',
            value = 'unlock'
        }
    },
    onSelect = function(option)
        print("选择了:", option.value)
    end
})

-- 带图片
exports['ak-lib']:Menu({
    id = 'shop_menu',
    title = '商店',
    options = {
        {
            label = '购买',
            image = 'https://example.com/item.png',
            value = 'buy'
        }
    },
    onSelect = function(option)
        print("选择了:", option.value)
    end
})

-- 禁用选项
exports['ak-lib']:Menu({
    id = 'menu',
    title = '菜单',
    options = {
        {
            label = '可用选项',
            value = 'available'
        },
        {
            label = '禁用选项',
            value = 'disabled',
            disabled = true,
            disabledReason = '需要等级 10'
        }
    },
    onSelect = function(option)
        print("选择了:", option.value)
    end
})

-- 子菜单
exports['ak-lib']:Menu({
    id = 'main_menu',
    title = '主菜单',
    options = {
        {
            label = '进入子菜单',
            value = 'submenu',
            submenu = {
                id = 'submenu',
                title = '子菜单',
                options = {
                    {
                        label = '子选项 1',
                        value = 'sub1'
                    },
                    {
                        label = '子选项 2',
                        value = 'sub2'
                    }
                },
                onSelect = function(option)
                    print("子菜单选择了:", option.value)
                end
            }
        }
    },
    onSelect = function(option)
        print("主菜单选择了:", option.value)
    end
})

-- 事件触发
exports['ak-lib']:Menu({
    id = 'action_menu',
    title = '操作菜单',
    options = {
        {
            label = '触发客户端事件',
            value = 'client_event',
            type = 'client',
            event = 'myplugin:doSomething',
            args = { arg1 = 'value1' }
        },
        {
            label = '触发服务端事件',
            value = 'server_event',
            type = 'server',
            event = 'myplugin:doSomething',
            args = { arg2 = 'value2' }
        }
    }
})

-- 检查菜单是否打开
local isOpen, menuId = exports['ak-lib']:IsMenuOpen()
if isOpen then
    print("菜单已打开，ID:", menuId)
end

-- 获取当前菜单数据
local menuData = exports['ak-lib']:GetCurrentMenu()
if menuData then
    print("当前菜单:", menuData.title)
end

-- 关闭菜单
exports['ak-lib']:CloseMenu()

-- 更新菜单
exports['ak-lib']:UpdateMenu({
    id = 'main_menu',
    title = '更新后的菜单',
    options = {
        {
            label = '新选项',
            value = 'new'
        }
    },
    onSelect = function(option)
        print("选择了:", option.value)
    end
})
```

#### 服务端：向玩家发送菜单

```lua
-- 向指定玩家打开菜单
exports['ak-lib']:Menu(source, {
    id = 'server_menu',
    title = '服务端菜单',
    options = {
        {
            label = '选项 1',
            value = 'option1'
        }
    },
    onSelect = function(option)
        print("玩家选择了:", option.value)
    end
})

-- 关闭指定玩家的菜单
exports['ak-lib']:CloseMenu(source)
```

### 📝 参数说明

#### data 参数（table）

| 字段         | 类型       | 说明          | 必需  | 默认值                    |
| ---------- | -------- | ----------- | --- | ---------------------- |
| `id`       | string   | 菜单 ID（唯一标识） | ✅ 是 | -                      |
| `title`    | string   | 菜单标题        | 否   | `'未命名'`                |
| `options`  | table\[] | 菜单选项列表      | ✅ 是 | -                      |
| `position` | string   | 位置（九宫格）     | 否   | `Config.Menu.Position` |
| `onSelect` | function | 选择选项时的回调    | 否   | -                      |
| `onClose`  | function | 关闭菜单时的回调    | 否   | -                      |

#### option 参数（table）

| 字段               | 类型      | 说明                                         | 必需  | 默认值     |
| ---------------- | ------- | ------------------------------------------ | --- | ------- |
| `label`          | string  | 选项标签                                       | ✅ 是 | -       |
| `description`    | string  | 选项描述                                       | 否   | -       |
| `value`          | any     | 选项值                                        | 否   | -       |
| `icon`           | string  | FontAwesome 图标类名                           | 否   | -       |
| `image`          | string  | 图片 URL                                     | 否   | -       |
| `preview`        | string  | 预览图片 URL（悬停显示）                             | 否   | -       |
| `disabled`       | boolean | 是否禁用                                       | 否   | `false` |
| `disabledReason` | string  | 禁用原因                                       | 否   | -       |
| `submenu`        | table   | 子菜单配置                                      | 否   | -       |
| `type`           | string  | 事件类型：`'client'` / `'server'` / `'command'` | 否   | -       |
| `event`          | string  | 事件名称（type 不为空时）                            | 否   | -       |
| `args`           | any     | 事件参数                                       | 否   | -       |
| `metadata`       | table   | 元数据显示                                      | 否   | -       |

#### 位置选项（position）

支持九宫格位置（默认：`'middle-right'`）：

* `'top-left'` - 左上角
* `'top-center'` - 顶部中间
* `'top-right'` - 右上角
* `'middle-left'` - 左边中间
* `'middle-center'` - 屏幕中央
* `'middle-right'` - 右边中间（默认）
* `'bottom-left'` - 左下角
* `'bottom-center'` - 底部中间
* `'bottom-right'` - 右下角

### ⚠️ 注意事项

1. **id 必需**：`id` 字段是必需的，用于唯一标识菜单。
2. **同时只能显示一个**：Menu 同时只能显示一个，新的会替换旧的。
3. **onSelect 回调**：回调函数接收 `option` 参数，包含选择的选项数据。
4. **事件触发**：使用 `type` 和 `event` 可以直接触发客户端/服务端事件，无需在 `onSelect` 中处理。
5. **子菜单**：支持多层嵌套子菜单，理论上可以无限层级。
6. **UpdateMenu**：使用 `UpdateMenu()` 更新菜单时，必须提供相同的 `id`。
7. **服务端调用**：服务端调用时需要提供 `target` 参数（玩家服务器 ID）。
8. **鼠标/键盘**：菜单支持鼠标和键盘操作，由 `Config.Menu.UseMouse` 和 `Config.Menu.EnableKeyboard` 控制。

### 🔗 相关文档

* 菜单说明


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ak-scripts.gitbook.io/docs/yi-lai/markdown/ui-mo-kuai-dao-chu/cai-dan-menu.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
