91 lines
3.6 KiB
Markdown
91 lines
3.6 KiB
Markdown
# L2 · 设置表单
|
||
|
||
> 前置:[L0](./01-hello-plugin.md)。声明式 schema:插件声明「要什么配置」,宿主负责渲染、持久化、实时回推。不用写任何 UI 代码。
|
||
|
||
## 1. 声明设置
|
||
|
||
```js
|
||
export default function definePlugin(api) {
|
||
api.ui.registerSettings({
|
||
items: [
|
||
{ type: 'string', key: 'apiKey', label: 'API Token', password: true, placeholder: 'sk-...' },
|
||
{ type: 'boolean', key: 'verbose', label: '详细日志', default: false },
|
||
{
|
||
type: 'select', key: 'endpoint', label: '接入点', default: 'prod',
|
||
options: [
|
||
{ value: 'prod', label: '生产' },
|
||
{ value: 'staging', label: '预发' }
|
||
]
|
||
},
|
||
{ type: 'button', key: 'test', label: '测试连接', variant: 'primary' }
|
||
]
|
||
})
|
||
}
|
||
```
|
||
|
||
保存后(开关切换或重启):
|
||
- 设置 → 插件 → **全局/项目** 作用域里,该插件行内出现 ⚙ 按钮(打开配置页)和「一级入口」开关
|
||
- **items 为空或不声明 → 两个控件都不出现**(这正是"留空则无一级入口按钮"的规则)
|
||
|
||
## 2. 一级入口
|
||
|
||
行内「一级入口」开关打开后,设置弹窗左侧导航「Agent 能力」组末尾出现以插件名命名的入口,点击进入该插件的独立配置页。用户随时可以关掉。
|
||
|
||
## 3. 读写值
|
||
|
||
```js
|
||
const values = api.ui.getSettingValues() // { apiKey: '...', verbose: false, endpoint: 'prod' }
|
||
// schema 里的 default 已合并——没被用户改过的键直接拿默认值
|
||
|
||
api.ui.onSettingsChange((next) => { // 用户在设置页改值后实时推送
|
||
values = next
|
||
api.log.info('settings changed', { endpoint: next.endpoint })
|
||
})
|
||
|
||
api.ui.onSettingsAction((key) => { // button 条目点击(key = 按钮项 key)
|
||
if (key === 'test') {
|
||
const ok = values.apiKey ? '✅' : '❌ 缺少 API Token'
|
||
api.ui.setStatusItem('test', { text: `连接测试 ${ok}`, tone: 'accent' })
|
||
}
|
||
})
|
||
```
|
||
|
||
值持久化在 `userData/aso-plugin-values.json`(按插件隔离),重装插件后仍在。
|
||
|
||
## 4. 13 种标准控件
|
||
|
||
| type | 说明 | 关键字段 |
|
||
|---|---|---|
|
||
| `string` | 单行输入 | `password` 掩码、`placeholder` |
|
||
| `text` | 多行文本 | `rows` |
|
||
| `number` | 数字 | `min` / `max` / `step` |
|
||
| `boolean` | 开关 | — |
|
||
| `select` | 下拉单选 | `options[{value,label}]` |
|
||
| `multiSelect` | 多选(chip 组) | `options` |
|
||
| `slider` | 滑条 | `min` / `max` 必填、`step` |
|
||
| `color` | 颜色(#rrggbb) | — |
|
||
| `path` | 文件/目录选择 | `mode: 'file' \| 'directory'` |
|
||
| `image` | 图片选择 + 缩略图 | — |
|
||
| `button` | 动作按钮 | `variant: 'primary' \| 'ghost'` |
|
||
| `info` | 静态说明 | — |
|
||
| `divider` | 分割线/小节标题 | `label?` |
|
||
|
||
全部条目支持 `label` / `description` / `default`(button/info/divider 除外)。
|
||
|
||
## 5. 设计约束(为什么是数据不是代码)
|
||
|
||
- schema 是**纯数据**:不允许函数/React 元素——宿主跨进程渲染并持久化快照
|
||
- 需要动态选项(比如扫描出来的设备列表)?在激活时计算好再 `registerSettings`,每次激活都会重新声明
|
||
- 需要复杂交互 UI?那不是设置的职责——走 [L4 React 组件](./05-renderer-components.md)
|
||
|
||
## 6. 验证
|
||
|
||
1. 重载插件 → 插件页该行出现 ⚙ 与「一级入口」
|
||
2. 打开配置页改一个值 → 日志出现 `settings changed`(`onSettingsChange` 生效)
|
||
3. 点按钮 → 状态胶囊出现(动作回调生效)
|
||
4. `userData/aso-plugin-values.json` 里能看到写入的键值
|
||
|
||
---
|
||
|
||
**上一篇** [L1](./02-tools-and-commands.md) · **下一篇**:[L3 UI 槽位](./04-ui-slots.md)——状态胶囊、面板、视图与 iframe 页。
|